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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions