So what are some strategies to really solve this problem? Is it basically impossible to implement a GC for a C-like language that will not leak at least a little memory?
- non-discriminated unions mixing pointers and non-pointers
- linking with C or other languages (as you can't scan their stack frames precisely)
- void*, memcpy, or other ways to move around memory which might have pointers.
A language without all of the above would be of limited utility. However, it's possible to dramatically improve the situation using:
- precise heap scanning - by knowing the type of each object allocated;
- precise stack scanning - by knowing the stack layout of all functions at all points throughout their execution;
- GC hooks for user-defined union types.