A brief look through the code and I do not see anything that enables incremental mode. From reading there home page is seems like boehm has incremental support enabled by default with OSs that support virtual memory. https://www.hboehm.info/gc/
It provides incremental and generational collection under operating systems which provide the right kind of virtual memory support. (Currently this includes SunOS, IRIX, OSF/1, Linux, and Windows, with varying restrictions.)
In Crystal, the GC provides a function to allocate memory, GC_malloc. We use that to allocate memory. Then the GC handles everything for us. When you call that function and there’s no allocated memory left, the GC will try to free some memory (this is when the GC runs). When there’s no memory to free it will allocate more and so on.
From the documentation, that is how it works in C too. You call GC_MALLOC() or similar, and it does the work as you described it is done in C. There is a GC_FREE() function in case you need it, but the point is to not use it.
So, for example, the code that creates a class object (where is it?) calls the Crystal function that ends up invoking GC_MALLOC()? Allocations like the ones for the unsafe internal buffers of Array do too?
The array buffer could be allocated in another way, and then we’d have a finalizer than would deallocate it. But we found it much simpler to have everything go through the GC and not worry about writing finalizers. Plus, if people use Pointer it’ll be safe because it goes through the GC and so on.
As far as I know crystal basically uses the “default” bdwgc compile (correct me if I’m wrong, it links against “libgc.a” at compile time so…you get whatever that was compiled with). However you could tweak some of them by compiling your own libgc and have it link to that.