Understanding ART Runtime GC Configuration and Heap Layout on Android R
The article explains Android R’s ART runtime garbage‑collection configuration and heap layout—including RegionSpace, ImageSpace, ZygoteSpace, non‑moving and LargeObject spaces—details concurrent, native, transition and blocking GC types, illustrates real‑world performance issues, and offers optimization strategies for developers.
Android applications run on the ART (Android Runtime) virtual machine, which provides the execution environment for Java code. The most critical components of ART are compilation, execution, and garbage collection (GC). Proper GC allows developers to focus on business logic without worrying about memory leaks.
This article briefly introduces the heap layout of the ART VM, common GC types, and related problem cases, offering insights for application optimization. The analysis is based on Android R (11) and a HelloWorld test application.
1. GC Configuration
Android R supports read barriers (kUseReadBarrier). During VM creation, the memory collector is set to:
foreground_collector_type = kCollectorTypeCC
background_collector_type = kCollectorTypeCCBackground
For the ConcurrentCopying (CC) collector, the foreground and background settings only affect parameters; the actual collector type is a single CC. When an app moves to the background, the system tries to release UI‑related objects and perform heap compaction.
2. Heap Layout
The ART VM binds a memory allocator to the collector type. With CC enabled, the main allocation region is RegionSpace , composed of 256 KB regions. The allocator type is kAllocatorTypeRegion . If generational GC is enabled (as in Android R), the default policy is Sticky (collect only newly allocated objects); otherwise it is Full (scan all spaces).
Key space types:
RegionSpace [~512 MB] – virtual address starts at 300 MB (0x12c00000). It consists of many 256 KB regions allocated via a simple bump‑pointer algorithm. When a region’s live objects exceed 75 % of its size, it is marked kRegionTypeUnevacFromSpace and reclaimed without copying; otherwise live objects are copied to a ToSpace region and the original region is freed.
ImageSpace [~4 MB] – created during Zygote startup by mapping the boot.art image. It is read‑only and not subject to allocation or GC.
ZygoteSpace [~3 MB] – contains objects that survive from Zygote creation to the first fork, enabling fast process startup.
Non‑moving Space [~61 MB] – allocated by Dlmalloc and stores class metadata objects such as Class , ArtMethod , and ArtField .
LOS (LargeObjectSpace) [~512 MB] – used for allocations larger than 12 KB (e.g., large strings or arrays). Android R implements LOS with a free‑list allocator.
Typical VM parameters observed on the test device:
[dalvik.vm.heapgrowthlimit]: [256m]
[dalvik.vm.heapsize]: [512m]
android:largeHeap="false"
3. Common GC Types
GCs are classified by the thread that performs them and by the trigger cause ( gc_cause ). The main categories are:
Concurrent (background) GC – runs on the HeapTaskDaemon thread, has minimal impact on UI, but can cause CPU contention on low‑end devices.
Native GC – manages native memory associated with Java objects (e.g., Bitmaps). Triggered when native allocations exceed thresholds (e.g., >300 KB).
CollectorTransition GC – occurs when an app moves from foreground to background (processState > 6), prompting a delayed concurrent GC with aggressive compaction.
Blocking GC – runs on the application’s working thread and includes Alloc GC (heap size near limit) and Explicit GC (manual Runtime.gc() or system‑initiated). These can pause the UI and cause ANR or OOM.
4. Representative Cases
Case 1 – Foreground BG GC causing scroll jank (Sina News V7.63.1): frequent background GC (Sticky/Full) leads to heap lock contention, pausing the UI thread.
Case 2 – Background apps generating high system load (multiple apps in background): simultaneous BG GC threads consume 30‑50 % CPU, degrading foreground responsiveness.
Case 3 – Native GC spikes (camera/album cold start): native allocations trigger NativeAlloc GC, increasing system load.
Case 4 – CollectorTransition GC during app exit (Tencent Video): delayed GC after background transition competes with foreground launch, causing animation stutter.
Case 5 – Alloc GC due to memory leaks (internal test tool, Douyin): heap reaches the limit, repeated Alloc GC fails to free memory, leading to OOM or complete freeze.
Case 6 – Explicit GC overuse (WeChat video live): frequent manual GC calls during UI interactions increase power consumption and cause unnecessary pauses.
Optimization suggestions across cases include reducing unnecessary explicit GC calls, improving memory‑leak detection, configuring android:largeHeap="true" only when needed, and strengthening background process control to limit GC‑induced CPU load.
5. Conclusion
The article provides an overview of GC configuration, heap layout, and practical case studies for Android R. It equips system developers and Android app engineers with knowledge to diagnose GC‑related performance problems and apply targeted optimizations.
OPPO Kernel Craftsman
Sharing Linux kernel-related cutting-edge technology, technical articles, technical news, and curated tutorials
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.