[solved] My memory leak or... PlayCanvas's?

Hi there!

I’m trying very hard to learn Play Canvas and it’s going quite well. A couple of times I had to choose a learning method of reading the engine code and engine’s objects in console, but it was an interesting journey!

Anyway, this time I don’t really know what to do - either I’m doing something wrong here or the engine and hopefully you’ll help me :).

So, basically I have a game with procedurally generated world and when I’m walking around long enough, what I’m getting is:

Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value 67108864, (2) compile with -s ALLOW_MEMORY_GROWTH=1 which adjusts the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program runs, or if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0

That’s strange, as the profiler shows quite stable VRAM statistics all the time:
image

I’ve put dozens of console.logs() to find out precisely, what line of code is causing the memory enlargement. I checked all the lists and dictionaries I have and I’m almost sure that’s none of them. As it turned out, logs showed the error is raised during the mesh creation process. More precise, collision mesh assignment:

    createMesh( data : MeshGenerationData ) {
        let model = new pc.Model();
        let pn = new pc.GraphNode();
        model.graph = pn;

        for ( let i = 0; i < data.triangles.count; i++ ) { // data.triangles.count=1 (those are subarrays of triangles)
            model.meshInstances.push( this.createMeshInstance( data, i, pn ) );
        }

        this.entity.addComponent("model", {
            type: 'asset'
        });

        this.entity.model.model = model;
        this.entity.model.castShadows = false;

        this.entity.addComponent("collision", {
            type: 'mesh'
        });
        
        let pn2 = new pc.GraphNode();
        let collisionModel = new pc.Model();
        collisionModel.graph = pn2;
        collisionModel.meshInstances.push( this.createColliderMeshInstance( data, pn2 ) );
        console.log( this.entity );
        this.entity.collision.model = collisionModel;
        console.log( "/\ Error happens here!" );

        this.entity.addComponent('rigidbody', {
            friction: 0.5,
            type: 'static'
        });
    }

Aside this code, the only related thing I’m doing is destroying the same entity later:

    delEntity( ch : ChunkInfo ) {
        if ( ch.entity ) {
            if ( ch.entity.model && ch.entity.model.model ) {
                ch.entity.model.model.destroy();
            }
            if ( ch.entity.collision && ch.entity.collision.model ) {
                ch.entity.collision.model.destroy();
            }
            ch.entity.destroy();
            ch.entity = null;
        }
    }

There’s no other code “touching” those entities - no adding components, removing them etc etc. So I assume the problem is somewhere within this code…

Maybe anyone of you had a similar problem before? :wink:

Another related question - am I doing right trying do debug a specific line of code causing the memory enlargement (as it’s always the same line)? Maybe I should handle it in some other way?

I tried to debug the browser memory after the crash and I’m not 100% sure if I can read it properly, but comparing the memory snapshot from game start to the memory snapshot from game crash:

It seems the only thing that grows is some kind of _cache vector3 array inside the Ammo memory system. That would relate well to concluding that the crash is related to applying new physics mesh.

Am I not freeing the collision mesh memory properly?

Profiling for 2 days, I ended up removing the collision system and writing my own, simplified for the game world :).