Subroutine Logo
Subroutine
← Back to Playground Languages Intermediate

Garbage Collection: Mark-and-Sweep & Heap Compaction

How modern language runtimes manage dynamic heap memory, trace root pointer graphs, and reclaim unreferenced object memory.

Published: 2026-07-26
#Garbage Collection#Memory Management#Go#Java#V8#Runtimes

Automatic memory management is one of the most critical responsibilities of modern programming language runtimes. Languages like Go, Java (JVM), and JavaScript (V8) abstract manual malloc/free calls using automatic Garbage Collectors (GC).

At the heart of tracing garbage collectors lies the classic Mark-and-Sweep algorithm.


1. Summary & Key Takeaways

  • Tracing Garbage Collection: The runtime periodically pauses or concurrently scans active thread stack frames (the Root Set) to find all reachable heap objects.
  • Phase 1: Mark Phase: Traverses pointer references recursively, setting a bit flag (e.g. isMarked = true) on all reachable nodes.
  • Phase 2: Sweep Phase: Iterates through the raw heap memory blocks. Any object without a mark flag is unreachable garbage and gets deallocated back to the free memory allocator.
  • Alternative Strategies: While Go and Java use tracing GCs, languages like Rust enforce compile-time ownership without runtime GC, and C++ uses RAII smart pointers (std::unique_ptr, std::shared_ptr).

2. Interactive Garbage Collection Playground

Use the interactive simulation below to test pointer graph tracing. You can sever pointer references between heap objects and click “Run Mark-and-Sweep GC” to watch reachable objects turn green while unreferenced orphan objects are swept into free memory!

Try Severing a Link

Click “Sever O2 → O4 Reference” and trigger the GC sweep. Watch how Object 4 turns into unreferenced garbage and gets swept out of heap memory!

Mark-and-Sweep Garbage CollectorInteractive Heap Tracing

Follow the 2-step GC process: Step 1: Mark reachable objects from Stack Roots, then Step 2: Sweep unreachable garbage memory!

Current Phase: 0. Idle Heap
Stack Frame / Root Set (Registers & Local Variables)Pointers pointing into Heap
Root Reference 1Local Variable userPtr
Points to → O1
Root Reference 2Local Variable sessionPtr
Points to → O2
Dynamic Heap Memory Pool (Objects Allocated in RAM)
O1128 KB
User Profile
UNTOUCHED
Pointers:→ O3
O2256 KB
Session Cache
UNTOUCHED
Pointers:→ O4
O3512 KB
Avatar Texture
UNTOUCHED
Pointers:None
O41024 KB
DB Connection
UNTOUCHED
Pointers:None
O52048 KB
Leaked Orphan
UNTOUCHED
Pointers:None
Garbage Collection & Memory Strategy
gc_demo.go
Go (Concurrent GC)
// Go Garbage Collector (Tricolor Mark-and-Sweep)
package main

import "runtime"

type Node struct {
    Data []byte
    Next *Node
}

func allocateAndSweep() {
    // Objects allocated on heap are automatically tracked by Go GC
    root := &Node{Data: make([]byte, 1024)}
    root.Next = &Node{Data: make([]byte, 2048)}

    // Sever reference -> Node becomes unreachable garbage
    root.Next = nil 

    // Trigger concurrent tricolor mark-sweep GC
    runtime.GC()
}

3. Comparing Memory Models Across Runtimes

LanguagePrimary Memory StrategyStop-The-World (STW) OverheadMemory Safety Model
GoConcurrent Tri-color Mark-and-SweepSub-millisecond (<1ms<1\text{ms})Automatic Garbage Collector
Java (JVM)Generational ZGC / G1 CollectorConfigurable (<10ms<10\text{ms})Automatic Garbage Collector
RustRAII & Compile-time OwnershipZero (No GC runtime)Affine Type System & Borrow Checker
C++Manual / Smart Pointers (std::unique_ptr)Zero (Deterministic destructors)Manual & RAII destructors
TypeScript / V8Generational Scavenger + Mark-SweepMinor idle-phase pausesAutomatic Garbage Collector
PythonReference Counting + Generational GCOccasional cyclic sweepAutomatic Hybrid Collector

4. Deep Dive: Tri-color Marking in Go

Modern production GCs (such as Go’s runtime) use Tri-color Marking to avoid locking the application during long Stop-The-World pauses:

  1. White Set: Candidate objects for memory reclamation (unvisited).
  2. Grey Set: Objects visited by root scanning whose child pointer targets have not yet been evaluated.
  3. Black Set: Reachable objects whose outgoing pointers have all been scanned.

When the mark phase completes, all remaining White objects are swept from the heap!