I have a simple Lua test project attached to demonstrate this issue I’ve been chasing for months: samplePlayers sometimes won’t release their memory, leading to a crash. This can be seen both in the Simulator (I’m on Mac) and on-device.
This is in SDK 2.6.2, but is not new: I believe it has been happening for over a year.
This leak is intermittent: the same code can run for HOURS with no leak. Then all of a sudden it will start to leak. When it does start, oddly, rebooting the Simulator or Playdate doesn’t reliably seem to help. It usually just keeps leaking—and may keep leaking for hours across multiple reboots. And then, like magic, the leak stops again. (Which can make it feel like recent code changes are somehow causing the leak to happen or not—but I finally know that’s not the case.)
Therefore, you may need to run this over a long period of time to see the leak begin (or to see it not happen as the case may be). Rebooting the app during testing is fine: it does not need to be run in one long session. The leak can begin in the middle of a previously-clean run, or immediately on launch. This app can run fine for hours—sometimes. Seems to be just luck. (Autorefreshing the malloc map view will make it very visible.) It will lead to a crash within seconds when it happens.
I’ve seen this with both PCM and ADPCM WAV files.
The attached project just reloads the same 1.7 MB sound and plays a bit of it, 5 times a second, always re-using the same global samplePlayer variable. (The same issue happens with less frequent playback and smaller files—this version just makes the issue more dramatic.)
This code makes my best attempt to clean up memory: before each new instance, the old one is stopped, assigned to nil, and then I even force a collectgarbage()
. (I’m not sure any of that cleanup is actually needed: it doesn’t seem to help. But the attempt is made.)
Here’s the core of what the app does, over and over via 200 ms timer:
soundPlayer:stop()
soundPlayer = nil
collectgarbage()
soundPlayer = snd.sampleplayer.new("TestSound")
soundChannel:addSource(soundPlayer)
soundPlayer:play()
Sample Player Memory Test.zip (5.7 MB)
I’m not 100% sure my code is following best memory management practices—maybe a leak is expected? But what seems wrong regardless is that it either leaks or not, arbitrarily.