GC feels like this magic box. Does great things for you without having to worry about memory leaks, which is great. But like anything that is magical you give up some control. I guess it's a tradeoff
Well, malloc and free are black boxes as well. And in typical implementations can potentially take arbitrary amounts of time to run, too. (Though they usually don't.)
It depends on your allocator - ptmalloc, the default linux allocator - is open source, and there's plenty of very robust open allocators (jemalloc, mimalloc, tcmalloc, etc). Understanding how your allocator works can be very important in certain contexts.
On windows I'd expect the default allocator to be a black box, but I might be wrong.
For garbage collection I strongly recommend this book (on top of the source code of your gc if available!)
https://gchandbook.org/
> On windows I'd expect the default allocator to be a black box, but I might be wrong.
The UCRT is at least "source available" on Windows, up to a point, and distributed with the Windows SDK. The release heap codepath is a bit boring:
malloc: C:\Program Files (x86)\Windows Kits\10\Source\10.0.19041.0\ucrt\heap\malloc.cpp
_malloc_base: C:\Program Files (x86)\Windows Kits\10\Source\10.0.19041.0\ucrt\heap\malloc_base.cpp
HeapAlloc: (kernel32.dll alias for ntdll.dll!RtlAllocateHeap() on my machine)
HeapAlloc itself is a bit more of a black box (AFAIK), and contains a lot of the fun details about the actual process of heap allocation - although there's a bunch of hooks, debug functions, documentation, articles, alternative implementations (ReactOS), etc.
Technically, but they tend to be much harder to hack on.
It's trivial to replace malloc/free with my_malloc/my_free - and integrating libraries that replace malloc/free as-is without renaming also tends to be straightforward. In C++, you can overload new/delete to use my_* with little hassle, or placement new to instantiate classes on previously allocated memory directly.
Meanwhile, C# and Java provide absolutely no means of creating instances of their classes via anything other than their built-in GCs. You can't just distribute a .exe or .jar with a replaced GC - instead, you need to create/distribute/install an entirely new runtime, and even that doesn't really provide any sane means of having multiple GCs living side by side. This is all theoretically technically possible, but orders of magnitude more work.
And yet so little code uses them that to eschew the builtin GC is to eschew basically the entire .NET framework. Even basic foreach loops go through IEnumerable interfaces - theoretically boxing even structs. They also come with different semantics - sometimes terrfiyingly subtly differences when combined with properties.
> and support for native heap management
IDisposable and friends are awkward fill-ins for proper RAII tools for native heaps.
That said, these options can be incrementally deployed in your existing codebase without resorting to another language, so they're more accessible options
> [links]
Hooking/replacing the GC seems more straightforward these days, than when I last looked into it though! Although, coreclr APIs won't help with Unity, or Mono. OpenJDK is at least used by modern Android these days, so perhaps there's a way to use it's GC customization options...?