Skip to content

Memory leaks when using node-v10 and node-v12 #829

@artemp

Description

@artemp

Memory leak(s)

To reproduce

https://github.com/nodejs/node-addon-examples/tree/master/napi-asyncworker-example/node-addon-api

then following script (MemoryLeak.js)


const runWorker = require('../build/Debug/napi-asyncworker-example-native');


function MemoryLeak(i, count) {
  if (i == count) return;
  let result = runWorker.runSimpleAsyncWorker(1, (err, result) => {
    if (err) {
      console.log("SimpleAsyncWorker returned an error: ", err);
    } else {
      if (i == count - 1) {
        //global.gc();
        //console.log(process.memoryUsage());
        //console.log(require('v8').getHeapStatistics());
        //console.log(require('v8').getHeapSpaceStatistics());
      }
      console.log("SimpleAsyncWorker returned '"+result+"'.");
    }
  });
  console.log("runSimpleAsyncWorker returned '"+result+"'.");
  MemoryLeak(++i, count);
}

//console.log(process.memoryUsage());
//console.log(require('v8').getHeapStatistics());
//console.log(require('v8').getHeapSpaceStatistics());
let i = 0;
MemoryLeak(i, 5);


node-v10.23.0 + node-addon-api-v3.0.2

valgrind --leak-check=yes  /opt/node-v10.23.0/bin/node test/MemoryLeak.js
==222152== 224 bytes in 4 blocks are definitely lost in loss record 35 of 41
==222152==    at 0x483BE63: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==222152==    by 0x75CFD9: napi_create_reference (in /opt/node-v10.23.0/bin/node)
==222152==    by 0x4863057: Napi::Reference<Napi::Function>::New(Napi::Function const&, unsigned int) (napi-inl.h:2153)
==222152==    by 0x4862292: Napi::Persistent(Napi::Function) (napi-inl.h:2317)
==222152==    by 0x4862683: Napi::AsyncWorker::AsyncWorker(Napi::Object const&, Napi::Function const&, char const*, Napi::Object const&) (napi-inl.h:3588)
==222152==    by 0x48625C1: Napi::AsyncWorker::AsyncWorker(Napi::Function const&, char const*, Napi::Object const&) (napi-inl.h:3564)
==222152==    by 0x4862534: Napi::AsyncWorker::AsyncWorker(Napi::Function const&, char const*) (napi-inl.h:3555)
==222152==    by 0x48624C5: Napi::AsyncWorker::AsyncWorker(Napi::Function const&) (napi-inl.h:3550)
==222152==    by 0x4861AA3: SimpleAsyncWorker::SimpleAsyncWorker(Napi::Function&, int) (SimpleAsyncWorker.cc:6)
==222152==    by 0x485E09A: runSimpleAsyncWorker(Napi::CallbackInfo const&) (RunSimpleAsyncWorker.cc:6)
==222152==    by 0x486139D: Napi::details::CallbackData<Napi::Value (*)(Napi::CallbackInfo const&), Napi::Value>::Wrapper(napi_env__*, napi_callback_info__*)::{lambda()#1}::operator()() const (napi-inl.h:82)
==222152==    by 0x4861753: napi_value__* Napi::details::WrapCallback<Napi::details::CallbackData<Napi::Value (*)(Napi::CallbackInfo const&), Napi::Value>::Wrapper(napi_env__*, napi_callback_info__*)::{lambda()#1}>(Napi::details::CallbackData<Napi::Value (*)(Napi::CallbackInfo const&), Napi::Value>::Wrapper(napi_env__*, napi_callback_info__*)::{lambda()#1}) (napi-inl.h:61)

looks interesting ^

==222152== LEAK SUMMARY:
==222152==    definitely lost: 544 bytes in 10 blocks
==222152==    indirectly lost: 16 bytes in 1 blocks
==222152==      possibly lost: 304 bytes in 1 blocks
==222152==    still reachable: 72,075 bytes in 1,076 blocks
==222152==         suppressed: 0 bytes in 0 blocks

Amount of definitely lost increases as number of iterations increases e.g calling MemoryLeak(i, 100) ^^

node-v14.11.0 + node-addon-api-v3.0.2

valgrind --leak-check=yes  /opt/node-v14.11.0/bin/node test/MemoryLeak.js
==222253== LEAK SUMMARY:
==222253==    definitely lost: 64 bytes in 1 blocks
==222253==    indirectly lost: 0 bytes in 0 blocks
==222253==      possibly lost: 304 bytes in 1 blocks
==222253==    still reachable: 8,191 bytes in 30 blocks
==222253==                       of which reachable via heuristic:
==222253==                         multipleinheritance: 48 bytes in 1 blocks
==222253==         suppressed: 0 bytes in 0 blocks

With node >=13 (tested with node-v13.12.0 and node-v14.11.0) there are constant results from memcheck no matter how many iterations as above.

It looks like there are memory leaks related to node-addon-api in node-10 and/or corresponding napi implementation ( and also in node-v12.16.1)

Is this known behaviour? Did anyone came across similar issues?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions