Description
See this minimal reproduction repository.
When creating several instances of a C++ object that is wrapped by ObjectWrap
, memory usage goes up forever unless the JavaScript job yields. Even though the JavaScript object is garbage collected and the JS heap size is stable. According to heaptrack
, suspicious allocations are occurring in napi_wrap
whenever the ObjectWrap
is created. I based the C++ addon on this documentation.
Clone the above repo and run:
npm install # for node-addon-api and node-gyp dependencies
npm run build # C++ build
node ./index.js
here is the loop in the minimal repro:
for (let i = 0; i < MAX_ITERS; ++i) {
const nativeObj = NativeObj.create();
// uncomment this and the application will not leak
// await new Promise(setImmediate);
}
On my Ubuntu 21.10 machine with Node.js 17.5, process.memoryUsage().rss
stabilizes at ~103MB
if yielding by uncommenting the await new Promise(setImmediate)
line.
Otherwise it goes up until the process is killed for eating too much memory.
Is this a memory leak? It does affect a larger addon from which I created the sample loop.
Running node with --trace_gc
and tracking the JavaScript heap, external, and buffer sizes demonstrate that the process memory growth is not from there, and that full mark-sweep garbage collections are occurring in parallel.