ENOMEM with exec/spawn - child process tries to reserve as much mem as parent

  • Version: v8.12.0 64-bit
  • Platform: Linux 4.15.0-1026 (Ubuntu 16.04)
  • Subsystem: child_process

A tiny exec call when Node.js is using at least half of the otherwise-available memory causes spawn ENOMEM:

// If your system has more than 4 GB of mem, repeat these two lines until >50% of memory is used:
let x = Buffer.allocUnsafe(2e9);
x.fill(2); // virtual -> reserved
// Causes ENOMEM even if there's >1 GB of available memory:
require("child_process").exec("pwd", console.log)
# (strace)
[pid  3017] clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7ffae3ea7a10) = -1 ENOMEM (Cannot allocate memory)

Apparently this is a common problem when using fork()/clone(), and using posix_spawn(3) avoids it.

I don't see any upstream issues in libuv for this.