Garbage collector not behaving as expected?

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.

However 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.

Even setting 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:

  1. GC step still runs even if GC won't, and:
  2. GC step takes such a long time and freezes the whole game when collectgarbage("count") indicates only a few MB of memory usage.
2 Likes