A tiny, conservative mark-and-sweep garbage collector for C written in ~500 lines of code.
TGC is a tiny garbage collector for the C programming language that automatically manages memory allocations. It uses a conservative mark-and-sweep algorithm to free memory when it becomes unreachable, helping developers avoid memory leaks without manual deallocation.
C developers working on applications where manual memory management is error-prone, such as long-running programs, embedded systems, or projects where simplicity and reduced memory leaks are priorities.
TGC offers an extremely lightweight and portable garbage collection solution with minimal code footprint (~500 lines), making it easy to integrate into existing C projects without complex dependencies or runtime overhead.
A Tiny Garbage Collector for C
Open-Awesome is built by the community, for the community. Submit a project, suggest an awesome list, or help improve the catalog on GitHub.
At only ~500 lines of code, tgc is incredibly lightweight and easy to audit or modify, making it ideal for embedding in projects without bloating the codebase.
Tested on Linux, Windows, and OSX, tgc avoids platform-specific tricks and relies on basic assumptions about the stack, ensuring wide compatibility for most architectures.
Allows registering cleanup functions for resources like file handles, enabling automatic resource management alongside memory freeing, as shown in the tgc_set_dtor function.
Provides functions to manually free memory, pause/resume collection, and mark allocations as roots or leaves, offering fine-grained performance tuning and management.
Designed for thread-local use, making it unsuitable for multi-threaded applications without significant modifications, as pointers from other threads are not considered reachable.
Requires pointers to always point to the start of allocations; incrementing pointers can cause premature freeing, complicating algorithms that use pointer arithmetic, as admitted in the README's F.A.Q.
Performance and correctness can be affected by compiler optimizations like inlining, requiring workarounds such as volatile function pointers, which adds complexity to integration.
Does not handle pointers in the static data segment or from non-tgc allocations, limiting its reachability analysis and potentially leaving memory leaks in edge cases, following its 'Worse Is Better' philosophy.