Deallocating heap objects when removing mesh from scene

As mentioned from StackOverflow:

The good news is, it’s not a bug. The bad news is it’s a change in the system that might catch a lot of people off-guard.

It looks like the old (< r68) way of handling object deallocation is _webglObjects is refreshed with each call to render. When you remove Mesh from the scene and nullify it, the _webglObjects refreshes–sans the Mesh–on the next render. After that, GC can safely remove the Mesh form the heap.

In r69dev, there is no magical refresh of _webglObjects. Removing and nullifying a Mesh leaves a reference to the Mesh in _webglObjects. GC then isn’t be able to remove the Mesh (or even the geometry/material) from the heap, resulting in my “leak.”

The thing I missed between r68 and r69dev is that when you remove a mesh in r69dev, you need to explicitly call dispose on it before nullifying it. Calling dispose triggers removeObject for the Mesh, which updates _webglObjects array. No more references lets GC happily collect the Mesh and associated data.

I’m mentioning it as a concern because bringing r68 code into r69dev was mostly seamless, and this issue wouldn’t have been on my radar if I weren’t dealing with large amounts of geometry. Also, it’s slightly odd not needing to call dispose on Object3D objects that are part of the scene, though I did see the method now exists.

Author: Fantashit

5 thoughts on “Deallocating heap objects when removing mesh from scene

  1. Here’s a start:

    scene.traverse( function ( object ) {
    	if ( object.geometry ) geometry.dispose();
    	if ( object.material ) material.dispose();
    } );
  2. If it helps, this is the dispose I have for scene BTW -maybe overkill, but seemed to work for my memory tests, you might have better.

    passing the scene to the function :

    function doDispose (obj)
            if (obj !== null)
                for (var i = 0; i < obj.children.length; i++)
                if (obj.geometry)
                    obj.geometry = undefined;
                if (obj.material)
                    if (
               = undefined;
                    obj.material = undefined;
            obj = undefined;

    Also I have this for renderer :


Comments are closed.