I didn't know you could mix and match (comic)

So, the obvious solution is to check if an object is still inside the WeakMap. If it is missing, it has been GC'd. This won't work.
The problem is that WeakMap and WeakSet are designed so that you cannot get at what's inside without already knowing it is there. In order to lookup an item, you need to already have that item. These collections don't even have a length method.
To check if an object is inside of a WeakMap, you must already have a reference to it, and therefore you are preventing it from being garbage collected.
So, what good are they? WeakMap is best used to link objects together. For example, if you have a bunch of <img> elements and you want to associate some data with them, you could simply do img.myextraproperty="blah". But your IDE may complain because the HTMLImageElement does not have this property. Instead, you can use WeakMap. If the extra property is a single value true then use a WeakSet.
In the code below, I use a WeakMap to associate a 1 gigabyte object with whatever you pass in. When the object is freed, and the garbage collector is run, you would expect at least 1 GB of memory to be freed as well. That is what the code checks for. The process takes at least 10 seconds, because it seems that Chrome only runs the garbage collector every 10 seconds.
/** Determines if an object is freed
@param obj is the object of interest
@param freeFn is a function that frees the object.
@returns a promise that resolves to {freed: boolean, memoryDiff:number}
@author Steve Hanov <steve.hanov@gmail.com>
*/
function isObjectFreed(obj, freeFn) {
return new Promise( (resolve) => {
if (!performance.memory) {
throw new Error("Browser not supported.");
}
// When obj is GC'd, the large array will also be GCd and the impact will
// be noticeable.
const allocSize = 1024*1024*1024;
const wm = new WeakMap([[obj, new Uint8Array(allocSize)]]);
// wait for memory counter to update
setTimeout( () => {
const before = performance.memory.usedJSHeapSize;
// Free the memory
freeFn();
// wait for GC to run, at least 10 seconds
setTimeout( () => {
const diff = before - performance.memory.usedJSHeapSize;
resolve({
freed: diff >= allocSize,
memoryDiff: diff - allocSize
});
}, 10000);
}, 100);
});
}
let foo = {bar:1};
isObjectFreed(foo, () => foo = null).then( (result) => {
document.write(`Object GCd:${result.freed}, ${result.memoryDiff} bytes freed`)
}, (error) => {
document.write(`Error: ${error.message}`)
})
Some time-saving shortcuts for C code that will make your coworkers scream. In Awe.
Why don't web pages start as fast as this computer from 1984?
JSON is horribly inefficient data format for data exchange between a web server and a browser. Here's how you can fix it.
People thought it was a comic, so I never corrected them.