So, I dug a bit deeper, and found a couple of things.
Firstly I realized why I experienced the behavior I described in my second comment, so I modified my code a bit, and I now successfully remove all btTriangleMesh
at runtime, without eny errors or hichups. For those that are interested, I made this script which can be attached to any entity with a mesh collider (using the render attribute), and it will clean out the relevant btTriangleMesh
ammo cache when the entity is destroyed (for current version of PlayCanvas):
var FreeAmmoMeshColliderMemory = pc.createScript('freeAmmoMeshColliderMemory');
FreeAmmoMeshColliderMemory.prototype.initialize = function() {
let meshID = this.entity.collision.render.meshes[0].id; // <-- NB! Assumes the collision component uses the "render" attribute
let trimeshCache = this.entity.collision.system._triMeshCache;
this.entity.on('destroy', () => {
// Free Ammo memory
Ammo.destroy(trimeshCache[meshID]);
// Remove reference so future collission components using the same mesh does not think it is already in the Ammo memory
delete trimeshCache[meshID];
// NB! There is still some leakage, most likely due to Ammo.btBvhTriangleMeshShape not being freed.
// see https://github.com/playcanvas/engine/blob/4075e5b7c292d66ff0a872f4cb604468430298cf/src/framework/components/collision/system.js#L437
// and https://forum.playcanvas.com/t/freeing-memory-from-ammo-js/35859/5
// If mesh is expected to be used as a collider many times repeatedly, it might better not to remove it from the cache at all.
})
};
This helps reduce the Ammo memory leakage, but I can confirm there is still quite significant leakage, as this fix only postponed the inevitable OOM crash. I managed to keep track of the btBvhTriangleMeshShape
that are created, and attempted to remove them from cache in a similar way (using Ammo.destroy()
) when they were no longer in use. However, this caused Ammo to throw a lot of errors and eventually crash completely:
I tried looking at the Ammo and Bullet documentation, but nothing seemed to explain why this happened, except perhaps an issue in the Ammo repo where Maksims reported a problem with Ammo itself not handling btBvhTriangleMeshShape
cache properly.
You wouldn’t happen to know more about this?
For now I made the stupidest hack for my game, where I catch the Ammo OOM error when it happens, save the users progress, and completely refresh the entire page, efficiently cleaning the entire cache (luckily this is most likely to happen during scene transitions, so it’s not as horrible as it sounds for the user).