agentleFS
rainoftimerainoftime/pl-skills/garbage-collector-implementer/SKILL.md

garbage-collector-implementer

Skill17 starsChanged 9 months agoApache-2.0View on GitHub

Implements tracing garbage collectors. Use when: (1) Building language

The file

We split this skill into the rules it gives an agent

9 rules. About 0 are common, 9 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈9

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Consider write barriers for incremental collection

    line 60
  2. Distinctive:

    Use thread-local allocation for speed

    line 62
  3. Distinctive:

    For real-time systems: Use real-time GC or custom allocators

    line 93
  4. Distinctive:

    For memory-constrained: Use manual memory management or arenas

    line 94
  5. Distinctive:

    For deterministic timing: Avoid GC pauses; use pooling

    line 95
  6. Distinctive:

    For bare metal: Use static allocation or custom allocators

    line 96
  7. Distinctive:

    Pause times: Stop-the-world collectors cause latency spikes

    line 107
  8. Distinctive:

    Techniques: Write barriers, dirty bits, concurrent marking

    line 157
  9. Distinctive:

    Must scan all threads' stacks:

    line 209

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Garbage Collector Implementer

Implements tracing garbage collectors (mark-compact, generational, etc.).

When to Use

  • Building language runtimes
  • Implementing interpreters/compilers
  • Learning memory management
  • Optimizing memory allocation

What This Skill Does

  1. Implements heap allocation - Object layout and allocation
  2. Builds tracing collectors - Mark-sweep, mark-compact, copying
  3. Handles roots - Stack and global roots
  4. Optimizes - Generational, incremental collection

Key Concepts

ConceptDescription
Root setInitial reachable references (stack, globals)
TracingFollow pointers from roots to find live objects
AllocationFinding space for new objects
CompactionDefragment heap after collection
GenerationsAge-based collection (young/old)

GC Algorithms Comparison

AlgorithmProsCons
Mark-SweepSimple, no copyingFragmentation, pause
Mark-CompactNo fragmentationMultiple passes, slow
CopyingFast, no fragmentationHalf memory, mutator copies
GenerationalShort pause, efficiencyComplexity

Tips

  • Track all root pointers carefully
  • Handle weak references specially
  • Consider write barriers for incremental collection
  • Profile pause times in production
  • Use thread-local allocation for speed

Related Skills

  • jit-compiler-builder - Build VM runtime
  • lambda-calculus-interpreter - Bytecode interpreter

Canonical References

ReferenceWhy It Matters
Jones & Lins, "Garbage Collection: Algorithms for Automatic Dynamic Memory Management" (Wiley, 1996)Definitive textbook on GC
Jones, Hosking & Moss, "The Garbage Collection Handbook: The Art of Automatic Memory Management" (Chapman & Hall, 2012)Updated comprehensive reference
Lieberman & Hewitt, "A Real-Time Garbage Collector Based on the Lifetimes of Objects" (CACM 1983)Generational GC origin
Ungar, "Generation Scavenging: A Non-disruptive High Performance Storage Reclamation Algorithm" (1984)Nursery/tenured generations
Blackburn & McKinley, "Immix: A Mark-Region Garbage Collector with Space Efficiency, Fast Collection, and Mutator Performance" (PLDI 2008)Modern high-throughput collector

Tradeoffs and Limitations

Algorithm Tradeoffs

AlgorithmPause TimeThroughputMemoryBest For
Mark-SweepMediumMediumHighEmbedded systems
Mark-CompactHighLowHighLong-running servers
CopyingLowHigh50%Real-time, short-lived objects
GenerationalLowHighModerateGeneral purpose
IncrementalPredictableLowerModerateInteractive apps

When NOT to Use GC

  • For real-time systems: Use real-time GC or custom allocators
  • For memory-constrained: Use manual memory management or arenas
  • For deterministic timing: Avoid GC pauses; use pooling
  • For bare metal: Use static allocation or custom allocators

Complexity Analysis

  • Mark-Sweep: O(n + m) where n = heap objects, m = marks
  • Copying: O(n) where n = live objects
  • Generational: O(n) for minor collections (young gen), full O(n) for major
  • Space overhead: Forwarding pointers, remembered sets

Limitations

  • Pause times: Stop-the-world collectors cause latency spikes
  • Fragmentation: Mark-sweep causes internal/external fragmentation
  • Overhead: GC costs 5-20% CPU time typically
  • Weak references: Need special handling for finalizers
  • Debugging: Memory leaks harder to find ( GC bugs are subtle)
  • Portability: GC depends on memory layout, pointer formats

Assessment Criteria

A high-quality GC implementation should have:

CriterionWhat to Look For
CorrectnessNever collects live objects
CompletenessCollects all unreachable objects
Pause timeLow latency (for real-time: <1ms)
ThroughputMinimal overhead on mutator
MemoryEfficient use of heap
ScalingWorks on multi-core

Quality Indicators

✅ Good: Correct, low pause, efficient ⚠️ Warning: Memory bloat, occasional pauses ❌ Bad: Collects live objects (memory corruption), doesn't terminate

Research Tools & Artifacts

Real-world garbage collectors to study:

SystemCollectorKey Innovation
HotSpot JVMG1, ZGC, ShenandoahGenerational, low-latency
Go runtimeMark-assistedConcurrent marking
OCamlMinor GCShort pauses
GraalVMTruffle GCMetacircular
RacketRing GCIncremental
Haskell GHCGenerationalParallel collection

Academic/Research GCs

  • Immix (Blackburn et al.) - High throughput
  • ZGC (Oracle) - Sub-millisecond pauses
  • Shenandoah (Red Hat) - Concurrent compaction
  • MMTk (Oxford) - Memory management tool kit

Research Frontiers

1. Concurrent GC

  • Goal: Reduce pause times by running concurrently
  • Techniques: Write barriers, dirty bits, concurrent marking
  • Papers: "Garbage Collection in Java 11" (Google I/O)
  • Tools: ZGC, Shenandoah, Go GC

2. Region-Based Allocation

  • Goal: Region-based memory management
  • Techniques: Regions with different lifetimes
  • Papers: "Memory Management with Regions" (Gay & Aiken)
  • Application: Rust's arena allocator

3. GC for Functional Languages

  • Goal: Efficient for immutable data
  • Techniques: Generational, incremental, persistent data structures
  • Papers: "The Design of Cryptographic Applications"
  • Application: Haskell, Clojure, OCaml

4. Real-Time GC

  • Goal: Predictable pause times
  • Techniques: Incremental, concurrent, hybrid
  • Papers: "Real-Time Garbage Collection" (Lieberman & Hewitt)
  • Application: Embedded systems, games

Implementation Pitfalls

PitfallReal ConsequenceSolution
Missing rootsMemory corruptionTrace all stack slots, globals
Write barrier bugsIncorrect collectionTest with pinned objects
FragmentationOut of memoryCompaction or copying
Pin handlingObjects can't moveHandle specially
FinalizersMemory leaksTrack finalizer queue

The "Write Barrier" Problem

Concurrent GC needs write barriers:

// Write barrier for generational GC
void write_barrier(void* obj, void* field, void* new_value) {
    // If storing old->new ref and new is in older gen
    if (is_heap_object(new_value) && 
        generation(new_value) < generation(obj)) {
        // Remember this store for minor GC
        remember_set_add(obj);
    }
    // Perform actual write
    *field = new_value;
}

The "Stack Scanning" Challenge

Must scan all threads' stacks:

void scan_roots() {
    for (Thread* t = all_threads; t != NULL; t = t->next) {
        // Get stack boundaries
        void* stack_top = t->stack_top;
        void* stack_bottom = t->stack_bottom;
        
        // Scan stack for pointers
        for (void* p = stack_bottom; p < stack_top; p += sizeof(void*)) {
            void* obj = *p;
            if (is_heap_object(obj)) {
                mark(obj);
            }
        }
    }
}

This is why GC pause times vary with stack depth!

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.