Skip to content

node-api: run finalizers directly from GC

The issue

Currently Reference finalizers are run inside of SetImmediate. In case if user code creates a lot of native objects in the main script, it could cause a significant memory pressure, even if the objects are properly released. This is because they are "collected" only inside of SetImmediate that follows the script run. See the issue: https://github.com/nodejs/node-addon-api/issues/1140

In the https://github.com/nodejs/node/commit/a74a6e3ba131752225a527d915593d7e413b1594 commit the processing of finalizers was moved from the GC second pass to the SetImmediate because:

  • finalizers may run some arbitrary JS code while some other JS code being executed.
  • finalizers may throw JavaScript exceptions which can affect behavior of other functions.

The solution

In this PR we are introducing new experimental behavior where the finalizers are run directly from the GC but they are not allowed to run JS code and must only call native code. Since the finalizers cannot affect the running JS code in any way, they are safe to run at any point.

  • When the finalizers run from GC, we disable running JS code and any Node-API that may run JS code.
  • Any unhandled Node-API error or JS exception will cause the process abort.

If a finalizer must run JS code, then it can do it by calling the new node_api_post_finalizer method which schedules the finalizer run in SetImmediate as it was before. The main difference is that previously we always scheduled finalizer runs in SetImmediate implicitly, and now code must do it explicitly.

Merge request reports

Loading