-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
memleak using worker and objects wrapping c++ instances #38816
Comments
https://nodejs.org/api/addons.html#addons_worker_support mentions what you need to do: Use We should really just not recommend using |
I am already using |
Here is a minimal sample outlining my current workaround: class FooWrap : public node::ObjectWrap {
public:
FooWrap(v8::Isolate* isolate) : mIsolate{isolate} {
node::AddEnvironmentCleanupHook(mIsolate, DeleteInstance, this);
}
virtual ~FooWrap() override {
if (mIsolate != nullptr) {
// The object is "deleted" before the cleanup-hook is called;
// most likely due to garbage collection during runtime.
// The hook has to be removed:
node::RemoveEnvironmentCleanupHook(mIsolate, DeleteInstance, this);
} else {
// DeleteInstance(..) was called during the environment cleanup process.
}
}
private:
static void DeleteInstance(void* data) {
FooWrap* wrapped = static_cast<FooWrap*>(data);
wrapped->mIsolate = nullptr;
delete wrapped;
}
v8::Isolate* mIsolate;
}; As mentioned in my last comment this seems rather "hacky" to me. |
It’s the same thing Node.js’s own internal objects do – we’ve done our best to make it fast (including for this specific reason).
That’s fair, but 99 % of new addon development happens with Node-API anyway, |
I ported my small sample to Node-API ( I still think some sort of warning/hint regarding this behavior of |
What steps will reproduce the bug?
Sample description
provided reproducer-sample: gist
The main thread continuously instantiates worker-threads.
Inside of these workers an instance of a wrapped C++ object is created (see Wrapping C++ objects).
These wrapped objects are not properly destroyed on worker-shutdown (assuming garbage-collection is not manually triggered before shutdown), causing a memory-leak.
Steps to reproduce the bug locally
node-gyp
if not already installed → run:npm i -g node-gyp
clone
the following gistnode-gyp configure
node-gyp build
node --expose-gc ./testAddon.js
How often does it reproduce? Is there a required condition?
always. no precondition.
What is the expected behavior?
Proper destruction of the wrapped objects.
expected console-output:
What do you see instead?
The wrapped objects are not destroyed and cause a memory-leak.
perceived console-output:
The instantiated objects allocate a large integer vector, so the effects of the memory-leak are also easily visible in "Task Manager".
Additional information
The same behavior also applies to wrapped objects instantiated inside the main thread.
There the problem is not as severe because the memory is "handed back" to the OS on process-shutdown.
A C++ developer developing a native addon still expects the destructor of the object to be called at some point, which makes this behavior problematic.
The text was updated successfully, but these errors were encountered: