Skip to content
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

Memory management questions #550

Closed
marco-ms opened this issue Sep 24, 2019 · 6 comments
Closed

Memory management questions #550

marco-ms opened this issue Sep 24, 2019 · 6 comments
Labels

Comments

@marco-ms
Copy link

marco-ms commented Sep 24, 2019

  1. I see that SuppressDestructor is used often in the object wrap examples, like:
    https://github.com/nodejs/node-addon-api/blob/master/doc/object_wrap.md
    // Call the SuppressDestruct() method on the static data prevent the calling
    // to this destructor to reset the reference when the environment is no longer
    // available.
    constructor.SuppressDestruct();

But what exactly means this comment? I honestly don't understand if I have to manage the life cycle of any object created by this code.
2. Similarly if using a Napi::FunctionReference created with Napi::Persistent() and assigned to a class member to call a JS callback at any point in time, should the code take care of dereferencing it at some point?
https://github.com/nodejs/node-addon-api/blob/master/doc/function_reference.md

@KevinEady
Copy link
Contributor

Simply put, the v8 engine works with reference counting for garbage collection. The Napi::Function func constructor function is created on the stack inside the Init method, but it stored statically in constructor. We need to tell the engine that we are still using this value even after Init finishes, which is why we store it in a reference.

Classes that extend Reference have a destructor to call napi_delete_reference on themselves unless SupressDestruct() has been called.

@mhdawson
Copy link
Member

mhdawson commented Oct 3, 2019

One small correction. I don't think that V8 uses reference counting, but that does not change the comment that if we use the method across methods, that we need to either have a reference to it in a live JavaScript Object or tell V8 that it needs to be kept alive.

@marco-ms
Copy link
Author

marco-ms commented Oct 14, 2019

Sure I understand now, still to complete a 100% shutdown of the module, some Uninit() method should dereference all these static properties then?
It is not clear to me when a node module goes out of scope, how exactly that works out on the allocated memory, but it could be lack of understanding of how Node modules are allocated/deallocated.

@gabrielschulhof
Copy link
Contributor

@marco-ms The life cycle of Node.js native addons coincides with that of the Node.js environment. This means that once a Node.js module is loaded, it is not unloaded unless the Node.js environment terminates. For the main thread, this means that modules are unloaded only when the process terminates. For worker threads, this means that modules are unloaded when the worker thread terminates. Until recently, strong references and weak references that were not garbage collected up until environment exit were not deleted. This changes with nodejs/node#28428 having landed. Now the environment will make one final pass over all remaining references and delete them before exiting.

@github-actions
Copy link
Contributor

This issue is stale because it has been open many days with no activity. It will be closed soon unless the stale label is removed or a comment is made.

@github-actions github-actions bot added the stale label Dec 17, 2020
@mhdawson
Copy link
Member

I'm going to close this as there has not been a response since the last response quite some time ago. Please let us know if you think that was not the right thing to do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants