On Thu Jul 13 10:09:15 2023 +0000, Jacek Caban wrote:
This is not exactly enough for weak references. Note that weak entry should also be released when key is released, which is an information that you don't feed to GC. For example:
var m = new WeakMap(); var k = {}; m.set(k, k); k = null;
In this example the entry may be collected, but unless I'm missing something, GC won't be able to do it as long as m is alive. BTW, it would be nice to have some tests for leaks. We could have, for example, two new host object. One would be purely for ref counting, while the other one could opaque it with a predictable single reference and a way to query current ref count.
var m = new WeakMap(); var t = createTestRef(); // a builtin function returning a builtin object var k = { val: t.get() }; // t.get() returns a separated object, who's ref count we will be testing m.set(k, k); ok(t.ref > 1, "map entry not released"); // t.ref is t.get()'s ref count, there is a reference from k.val k = null; CollectGarbage(); ok(t.ref === 1, "map entry not released"); // there are no more JS references
You're right, it won't get released until m is freed, even though the value is not technically accessible. I think this also applies if there's an object as the value that's holding a ref to the key, but that object is not accessible anywhere else (basically, cyclic ref with the WeakMap).
Not sure how "bad" this is, since it's not a permanent leak though, I'll have to weigh the alternatives, but I'll look into writing tests for it.