Memory leaks: a reference keeps the object alive
Finishing a scene does not automatically make its event listener unreachable.
The player closed the scene, but a global event target still holds a callback that uses its data. To the developer, the scene has finished. To the garbage collector, it remains reachable.
function mount(scene) {
const onResize = () => scene.resize();
window.addEventListener('resize', onResize);
return () => window.removeEventListener('resize', onResize);
}
mount(scene) returns a cleanup function. When the scene is no longer needed, that function must be called: it removes the onResize listener from window. The call to removeEventListener must receive the same handler that was originally added.
To find a leak in an application, we can compare memory snapshots after opening and closing the scene several times and check what still keeps it in memory.