Supporting circular references that can be garbage collected.
In JavaScript I can make two objects that reference each other and they'll still be GCed.
function makeObjectsThatReferenceEachOtherButLeakNoReferences() {
const a = new Uint8Array(1024);
const b = new Uint8Array(1024);
a.other = b; // make them reference each other
b.other = a;
}
makeObjectsThatReferenceEachOtherButLeakNoReferences();
In the code above, even though a circular reference was created, JavaScript will see there is no path from root and garbage collect the objects.
Is it possible to do the same in C++ Napi. If I make a class
class MyClass : public Napi::ObjectWrap<MyClass> {
...
Napi::Reference<Napi::Object> storedObjectRef_;
};
And I manage to make 2 instanced of MyClass and set storedObjectRef_ so they point to each other, AFAICT these objects will never be garbage collected.
Is there a solution?
Note: I know I could add some function close or whatever to null out storedObjectRef_ but that's not really the question I'm asking. I'm trying to reproduce JS garbage collecting circular references.
One idea I guess, which appears to work, is I could add a JS property to MyClass. So instead of Napi::Reference<Napi::Object> storageObjectRef_ I'd use Get, Set as in
this->Value().Set("storageObjectRef", otherObject);
but unfortunately that's visible externally which I don't want. I could use a symbol but those are inspectable too. Though it might be better than nothing if there is no other solutions.
I'm pretty sure napi doesn't support this but it occurs to me in JS there are private properties
class Foo {
#myPrivProp
}
if there was a way to make them from a C++ class in DefineClass that would also solve the issue .
It is possible to make an Napi::Reference as a weak reference:
https://github.com/nodejs/node-addon-api/blob/ff6a672b07502116a4db8fd3c7000ba6dcb62ec8/napi.h#L1768-L1771
Unless I'm mis-understanding, a weak reference is not a solution. The JS example above, those are not weak references. Just like the JS, I need 2 objects to be able to point to each other and keep each other alive as long as they are both referenced but, like JS, if there is no path from root they get GCed.
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.