n-api: reduce gc finalization stress
https://github.com/nodejs/node/pull/24494 fixed a crash but resulted in increased stress on gc finalization. A leak was reported in https://github.com/nodejs/node/issues/26667 which we are still investigating. As part of this investigation I realized we can optimize to reduce amount of deferred finalization. Regardless of the root cause of the leak this should be a good optimization. It also resolves the leak for the case being reported in #26667. The OP in 26667 has confirmed that he can still recreate the original problem that 24494 fixed and that the fix still works with this optimization PR-URL: https://github.com/nodejs/node/pull/27085 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
b925379f50
commit
ff89670902
@ -227,10 +227,11 @@ class Reference : private Finalizer {
|
|||||||
// from one of Unwrap or napi_delete_reference.
|
// from one of Unwrap or napi_delete_reference.
|
||||||
//
|
//
|
||||||
// When it is called from Unwrap or napi_delete_reference we only
|
// When it is called from Unwrap or napi_delete_reference we only
|
||||||
// want to do the delete if the finalizer has already run,
|
// want to do the delete if the finalizer has already run or
|
||||||
|
// cannot have been queued to run (ie the reference count is > 0),
|
||||||
// otherwise we may crash when the finalizer does run.
|
// otherwise we may crash when the finalizer does run.
|
||||||
// If the finalizer has not already run delay the delete until
|
// If the finalizer may have been queued and has not already run
|
||||||
// the finalizer runs by not doing the delete
|
// delay the delete until the finalizer runs by not doing the delete
|
||||||
// and setting _delete_self to true so that the finalizer will
|
// and setting _delete_self to true so that the finalizer will
|
||||||
// delete it when it runs.
|
// delete it when it runs.
|
||||||
//
|
//
|
||||||
@ -238,13 +239,14 @@ class Reference : private Finalizer {
|
|||||||
// the finalizer and _delete_self is set. In this case we
|
// the finalizer and _delete_self is set. In this case we
|
||||||
// know we need to do the deletion so just do it.
|
// know we need to do the deletion so just do it.
|
||||||
static void Delete(Reference* reference) {
|
static void Delete(Reference* reference) {
|
||||||
if ((reference->_delete_self) || (reference->_finalize_ran)) {
|
if ((reference->RefCount() != 0) ||
|
||||||
|
(reference->_delete_self) ||
|
||||||
|
(reference->_finalize_ran)) {
|
||||||
delete reference;
|
delete reference;
|
||||||
} else {
|
} else {
|
||||||
// reduce the reference count to 0 and defer until
|
// defer until finalizer runs as
|
||||||
// finalizer runs
|
// it may alread be queued
|
||||||
reference->_delete_self = true;
|
reference->_delete_self = true;
|
||||||
while (reference->Unref() != 0) {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user