Major memory leak with removeSprites(array) and sprite.removeAll()

I am using the Windows Simulator, I'm not sure if this is a problem on both simulator and device.

I was messing with a sprite benchmark @GloryFish posted on the Discord (Discord), and I noticed the performance would drop significantly after going up to 128x128 sprites and then back down to 5x5 sprites a few times (going to 512x512 crashes every time, probably overloading the stack or something). Even though gfx.sprite.spriteCount() indicates that the sprites have been removed from the display list, the performance does not indicate that they have stopped being processed. After trying several things, I found a solution that leads me to believe that playdate.graphics.sprite.removeAll() and playdate.graphics.sprite.removeSprites(spriteArray) are not working correctly. If instead you use sprite:remove(), the performance recovers properly when adding and removing a large amount of sprites.

Here is a video demonstrating the sprite.removeSprites() performance drop. The same thing happens with sprite.removeAll().

And here is a video using sprite:remove() instead, as you can see the performance does not drop after adding and removing a lot of sprites.

5 Likes

I wonder if the garbage collection takes longer to run on a contiguous array of objects removed vs getting near real time gc on each object manually removed. I noticed when provided objects to lua from C that lua is very happy to drop single objects as fast as it can.

Or the whole array just isn’t released properly.

Thanks for the report!

It looks like we weren't releasing our internal reference to sprites when using removeAll() or removeSprites().

I have a fix in, and it should be in our next release.

Until then, hopefully the workaround mentioned in the linked thread can tide you over:

for k, v in pairs(testSprites) do
    v:remove()
end
5 Likes