Description
Hey PlayCanvas team, we were doing some memory leaks investigations on our app that uses PlayCanvas engine and we noticed a lot of leaked buffers after the entities containing the particle systems are destroyed. The way we're spawning them is we have some templates with entities with various particle systems and our VFX instantiates them in the scene on demand and then it destroys them when the particle systems have finished playing.
So when doing comparison of heap snapshots before and after spawning those vfx entities a few times we would see something like this:
A lot of JSArrayBufferData
objects that are being retained by the meshInstances
property of the StandardMaterial
for the particular defaultMaterial
.
Upon investigation we determined that this was due to the fact that the meshInstance
property of the ParticleEmitter
is not destroyed when the emitter's destroy
method is called (and hence _destroyResources
) and when the code reaches the point of destroying the material
property it references the meshInstance
inside the defaultMaterial
where it remains forever, leaking.
Adding these lines of code to the _destroyResources
method solves the problem
this.colorParam?.destroy();
this.colorParam = null;
// newly added
this.meshInstance?.destroy();
this.meshInstance = null;
this.mesh?.destroy();
this.mesh = null;
///
this.vertexBuffer?.destroy();
this.vertexBuffer = undefined; // we are testing if vb is undefined in some code, no idea why
this.indexBuffer?.destroy();
this.indexBuffer = undefined;
this.material?.destroy();
this.material = null;
We didn't create a PR because we were not sure if not destroying the meshInstance
is intentional or an oversight, but it doesn't seem to have any obvious side effects, except getting rid of the memory leaks