Fundamentals 33 min read

Understanding Dart VM Garbage Collection and Memory Management

The article explains Dart VM’s generational garbage collection, detailing object allocation, the young‑generation Scavenge copying collector, old‑generation Mark‑Sweep and Mark‑Compact algorithms, safepoints, write‑barrier mechanics, debugging a write‑protect crash, and the importance of logging for memory‑management analysis.

DeWu Technology
DeWu Technology
DeWu Technology
Understanding Dart VM Garbage Collection and Memory Management

GC (Garbage Collection) is an automatic heap memory management mechanism. In Flutter, Dart is the primary language and relies on GC to free objects without manual intervention.

The article first outlines Dart object allocation, showing how a constructor call is compiled into AllocateObject and StaticCall IL instructions, which later become AOT machine code via GenerateNecessaryAllocationStubs() and Object::Allocate() .

It then describes the layout of a Dart object: a header word (type tag, mark bits, length) followed by instance fields. Objects are represented as UntaggedObject with ObjectPtr pointers, and traversal of fields uses HeapSize() to compute addresses.

DartVM GC Overview

DartVM uses a generational heap with young and old generations. Young generation GC uses the Scavenge (copying) algorithm, while the old generation employs Mark‑Sweep and Mark‑Compact.

Scavenge

Scavenge runs in parallel threads (controlled by FLAG_scavenger_tasks ). Roots are processed, objects are copied from from‑space to to‑space, and forwarding pointers are installed. Promoted objects are recorded in promoted_list_ and later processed.

Mark‑Sweep

Mark‑Sweep consists of a marking phase (parallel MarkObjects() traverses roots, pushes marked objects onto work_list_ ) and a sweep phase that frees unmarked objects. The algorithm may suffer from fragmentation.

Mark‑Compact

Mark‑Compact adds a compaction phase after marking. It computes new addresses for live objects (PlanPage/PlanBlock), then slides objects to their new locations (SlidePage/SlideBlock) and updates pointers.

Safepoints

GC operations that require the heap to be quiescent use safepoints. Mutator threads are paused via GcSafepointOperationScope , ensuring no heap modifications during critical phases.

Write Barriers and Elimination

During concurrent marking, write barriers ensure that stores from old‑generation objects to young‑generation objects are recorded in the RememberedSet, and that stores to unmarked old objects trigger marking. The article discusses conditions where write barriers can be safely eliminated to reduce overhead.

Debugging GC Issues

The author recounts a real‑world GC crash caused by old‑generation pages being write‑protected, leading to illegal writes during marking. Various hypotheses (multiple isolates, write‑barrier elimination) were tested, and a temporary fix added address validation via PageSpace::ContainsUnsafe() . Further investigation revealed that PageSpace::WriteProtect() made old pages read‑only, causing the crash.

Conclusion

Understanding the full Dart VM GC pipeline clarifies generational collection, the trade‑offs of different algorithms, and the importance of logging for diagnosing memory issues. Future work includes persisting GC logs for deeper performance analysis.

DartMemory ManagementGarbage CollectionGC AlgorithmsVM
DeWu Technology
Written by

DeWu Technology

A platform for sharing and discussing tech knowledge, guiding you toward the cloud of technology.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.