If you load the below test case via a local web server in Chrome then manually trigger garbage collection in the memory tab of Chrome's developer tools, clicking the "Log alive counts" button then gives:
withoutStore: 0
withStore: 1000
<!doctype html>
<html>
<head>
<title>Test case</title>
<script type="module">
import { define, html, store } from "https://esm.sh/hybrids@^9";
const AppState = { count: 0 };
define({
tag: 'with-store',
value: store(AppState),
});
define ({
tag: 'without-store',
value: 0
});
let withoutStoreRefs = [];
let withStoreRefs = [];
let count = 0;
for (let i = 0; i < 1000; ++i) {
let withStore = document.createElement("with-store");
let withoutStore = document.createElement("without-store");
document.body.append(withStore, withoutStore);
// prime the cache entries
count += withStore.value + withoutStore.value;
withStoreRefs.push(new WeakRef(withStore));
withoutStoreRefs.push(new WeakRef(withoutStore));
withStore.remove();
withoutStore.remove();
withStore = null;
withoutStore = null;
}
function aliveCount(refs) {
return refs.reduce((count, ref) => count + Boolean(ref.deref()), 0);
}
let output = document.createElement('div');
let button = document.createElement('button');
button.innerText = "Log alive counts";
button.addEventListener('click', () => output.innerHTML = `
withoutStore: ${aliveCount(withoutStoreRefs)}<br>
withStore: ${aliveCount(withStoreRefs)}
`);
document.body.append(button, output);
</script>
</head>
<body>
</body>
</html>
From looking at cache.js, perhaps you could add a single weak reference (for set identity) on cache entries when they are created:
entry = {
key,
target,
...
}
entry.ref = new WeakRef(entry);
and then use those in the contexts set instead to avoid holding a strong reference to the originating host?
if (context) {
...
entry.context.add(context.ref)
}
If you load the below test case via a local web server in Chrome then manually trigger garbage collection in the memory tab of Chrome's developer tools, clicking the "Log alive counts" button then gives:
From looking at cache.js, perhaps you could add a single weak reference (for set identity) on cache entries when they are created:
and then use those in the contexts set instead to avoid holding a strong reference to the originating host?