Cesium Memory leaks after primitive features are destroyed

He guys, We noticed recently that there seems to be a memory leak within cesium after primitive objects are destroyed. I am having trouble tracking it down to fix it. My hope is by pointing it out, you guys will immediately know what to suspect. We have a case where a user can import feature data into vector overlays and delete the overlays and then import more feature data. The leak is very noticeable when there are large amounts of features being added and deleted. I have created a simple test in the Hello World example that demonstrates this.

Replace this

///////////////////////////////////////////////////////////////////////////

// INSERT CODE HERE to create graphics primitives in the scene.

///////////////////////////////////////////////////////////////////////////

With …

var canvas2 = document.createElement(‘canvas’);

canvas2.width = 16;

canvas2.height = 16;

var context2D = canvas2.getContext(‘2d’);

context2D.beginPath();

context2D.arc(8, 8, 8, 0, Cesium.Math.TWO_PI, true);

context2D.closePath();

context2D.fillStyle=‘rgb(255, 255, 255)’;

context2D.fill();

var billboards = new Cesium.BillboardCollection();

var textureAtlas = scene.getContext().createTextureAtlas({image : canvas2});

billboards.setTextureAtlas(textureAtlas);

scene.getPrimitives().add(billboards);

var addAbunch = function(){

for (var i=0; i<500; i++){

for (var j = 0; j < 500; j++) {

billboards.add({

position: ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-75.59777 + i, 40.03883+j)),

color: {

red: 1.0,

blue: 0.0,

green: 0.0,

alpha: 1.0

},

scale: 0.5,

imageIndex: 0

});

}

}

}

var removeAll = function(){

billboards.removeAll();

}

Replace this

case ‘2’.charCodeAt(0): // ‘2’ -> Columbus View

transitioner.morphToColumbusView();

break;

case ‘1’.charCodeAt(0): // ‘1’ -> 2D map

transitioner.morphTo2D();

With …

case ‘2’.charCodeAt(0):

removeAll();

break;

case ‘1’.charCodeAt(0):

addAbunch();

Then, open your task manager and watch your browser memory consumption will spike when you hit the 1 key, but hitting the 2 key does not bring it back down after removeall.

It happens with polylinecollection as well. Not sure about polygons, but I have also confirmed that this memory leak did not always exist in Cesium. I think it showed up around August.

I found it.

Renderer/Context.js: (starting at line 2753)

        function _createPickId(object) {
            // TODO: Use alpha?
            if (++nextRgb.blue === 256) {
                nextRgb.blue = 0;

                if (++nextRgb.green === 256) {
                    nextRgb.green = 0;

                    if (++nextRgb.red === 256) {
                        throw new RuntimeError('Out of unique Rgb colors.');
                    }
                }
            }

            var pickId = {
                unnormalizedRgb : new Color(nextRgb.red, nextRgb.green, nextRgb.blue, 1.0),
                normalizedRgba : Color.fromBytes(nextRgb.red, nextRgb.green, nextRgb.blue, 255.0),
                destroy : function() {
                    // TODO: Remove from objects [OR THERE'S A MASSIVE MEMORY LEAK]
                    return null;
                }
            };

            objects[rgbToObjectIndex(pickId.unnormalizedRgb)] = object;

            return pickId;
        }

I replaced the TODO line with
delete objects[rgbToObjectIndex(pickId.unnormalizedRgb)]
And it seems to work. Does that make sense?

I’ll take a look and let you guys know. Thanks for the info.

Patrick

I took a quick look, and I agree that David’s pick changes should fix it. However, at least in Chrome on Windows, it doesn’t appear to be the complete fix. I submitted https://github.com/AnalyticalGraphicsInc/cesium/issues/398

I’ll be able to take a closer look in a few weeks, but anyone else is welcome to investigate in the meantime.

Patrick