Node heap size problem


Problem

So, in my case main problem was issue with my capistrano deployment.

My DigitalOcean droplet has very limited memory size, and adding some swap doesn’t solve my problem.

So I’m deploying my code with simple Capistrano script like this:

bundle exec cap production deploy

But, ass you can see below, node process on assets:precompile step was failed with:

JavaScript heap out of memory

Logs

Nothing special here, just out of memory because of my assets compilation issue.

Tasks: TOP => deploy:assets:precompile
(See full trace by running task with --trace)
The deploy has failed with an error: Exception while executing on host 157.230.216.60: rake exit status: 1
yarn install v1.22.11
[1/4] Resolving packages...
success Already up-to-date.
Done in 1.36s.
Compiling...
Compilation failed:
Though the "loose" option was set to "false" in your @babel/preset-env config, it will not be used for @babel/plugin-proposal-private-methods since the "loose" mode option was set to "true" for @babel/plugin-proposal-class-properties.
The "loose" option must be the same for @babel/plugin-proposal-class-properties, @babel/plugin-proposal-private-methods and @babel/plugin-proposal-private-property-in-object (when they are enabled): you can silence this warning by explicitly adding
	["@babel/plugin-proposal-private-methods", { "loose": true }]
to the "plugins" section of your Babel config.
Though the "loose" option was set to "false" in your @babel/preset-env config, it will not be used for @babel/plugin-proposal-private-methods since the "loose" mode option was set to "true" for @babel/plugin-proposal-class-properties.
The "loose" option must be the same for @babel/plugin-proposal-class-properties, @babel/plugin-proposal-private-methods and @babel/plugin-proposal-private-property-in-object (when they are enabled): you can silence this warning by explicitly adding
	["@babel/plugin-proposal-private-methods", { "loose": true }]
to the "plugins" section of your Babel config.
Though the "loose" option was set to "false" in your @babel/preset-env config, it will not be used for @babel/plugin-proposal-private-methods since the "loose" mode option was set to "true" for @babel/plugin-proposal-class-properties.
The "loose" option must be the same for @babel/plugin-proposal-class-properties, @babel/plugin-proposal-private-methods and @babel/plugin-proposal-private-property-in-object (when they are enabled): you can silence this warning by explicitly adding
	["@babel/plugin-proposal-private-methods", { "loose": true }]
to the "plugins" section of your Babel config.
[11653:0x4a6ecd0]    23462 ms: Scavenge (reduce) 488.2 (493.2) -> 487.7 (493.5) MB, 16.8 / 0.0 ms  (average mu = 0.270, current mu = 0.247) allocation failure
[11653:0x4a6ecd0]    23482 ms: Scavenge (reduce) 488.4 (490.5) -> 487.9 (492.0) MB, 18.7 / 0.0 ms  (average mu = 0.270, current mu = 0.247) allocation failure
[11653:0x4a6ecd0]    23502 ms: Scavenge (reduce) 488.7 (491.0) -> 488.1 (492.0) MB, 18.0 / 0.0 ms  (average mu = 0.270, current mu = 0.247) allocation failure
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 0xa25510 node::Abort() [node]
 2: 0x9664d3 node::FatalError(char const*, char const*) [node]
 3: 0xb9a8be v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
 4: 0xb9ac37 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
 5: 0xd56ca5  [node]
 6: 0xd5782f  [node]
 7: 0xd6566b v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
 8: 0xd6922c v8::internal::Heap::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [node]
 9: 0xd3790b v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationType, v8::internal::AllocationOrigin) [node]
10: 0x107fd40 v8::internal::Runtime_AllocateInOldGeneration(int, unsigned long*, v8::internal::Isolate*) [node]
11: 0x1426919  [node]
rake stderr: Nothing written

** DEPLOY FAILED
** Refer to log/capistrano.log for details. Here are the last 20 lines:

Solution

First of all let’s check Node’s documentation:

Node has a default max memory usage of less than 2GB on some 64bit systems.

This can cause unexpected memory issues. It’s possible to adjust the max memory ceiling using a command line flag passed into node:

--max-old-space-size=<memory in MB>

The flag can be difficult to ensure is being used. Especially when node processes are forked.

The best way to ensure this setting will be picked up by all node processes within the environment is to apply this setting directly to an environment variable NODE_OPTIONS.

So, just add to your environment:

NODE_OPTIONS=--max_old_space_size=4096

Enjoy!