I've been getting to grips with the SDK for a couple of weeks and had some unexpected behaviour with the garbage collector today. I've been getting some pretty significant performance drops on device due to the garbage collector running, which obviously isn't unusual on the face of it. However, I've had trouble getting the garbage collector to respect the settings I'm providing through the API methods.
playdate.setMinimumGCTime(ms) seems to work as expected; I can set it to an arbitrarily high number and see the effect in the sampler.
playdate.setGCScaling(min, max) doesn't quite work as I'd expect. My understanding was that
playdate.setGCScaling(1, 1) and
playdate.setMinimumGCTime(0) would effectively disable the garbage collector since it wouldn't actually run unless the device was literally about to OOM. But I still see a
GC step line logged in the sampler in a nasty spike.
playdate.setCollectsGarbage(false) doesn't seem to make a difference, and the garbage collector still seems to run when it feels like.
Am I missing something here? Does
GC mean something different to
GC step in this context, and is there anything I can do to get more control over the situation?
EDIT: wrote this quite late, just to clarify some things in the light of day. My motivation for understanding this is for a game that is much more CPU intensive than it is memory intensive, so getting some control over the garbage collector and reclaiming those CPU cycles would be nice. I understand the general concepts behind garbage collection (i.e. two or more separate processes for 'identifying garbage' and 'collecting garbage', e.g. mark and sweep), and my initial thought was the
GC step would be the 'mark' equivalent and
GC was the 'sweep' equivalent. However, it seems odd that:
GC stepstill runs even if
GC steptakes such a long time and freezes the whole game when
collectgarbage("count")indicates only a few MB of memory usage.