Mobile Development 23 min read

Why Android Apps Stutter: Deep Dive into Dalvik & ART Garbage Collection

This article explains the memory allocation and garbage‑collection mechanisms of Android’s Dalvik and ART runtimes, compares their algorithms, describes GC triggers, logs, and offers practical tips to reduce frame drops caused by frequent GC cycles.

Tencent TDS Service
Tencent TDS Service
Tencent TDS Service
Why Android Apps Stutter: Deep Dive into Dalvik & ART Garbage Collection

Preface

The motivation for writing about Android GC came from investigating image‑scroll lag on a Meizu phone, where continuous GC caused frame drops; the article explores memory allocation, GC principles, why GC repeats, differences between GC_ALLOC and GC_CONCURRENT, and ways to enlarge the heap to reduce GC frequency.

1. JVM Memory Reclamation Mechanism

1.1 Reclamation Algorithms

Mark and Sweep GC

Starting from the GC Roots set, the whole heap is traversed, retaining objects reachable directly or indirectly from the roots; unreachable objects are reclaimed, which may pause other threads and cause fragmentation.

Copying Algorithm

The heap is split into two halves; live objects are copied from the active half to the unused half during GC, then the roles of the halves are swapped, completing reclamation.

Mark‑Compact Algorithm

After marking reachable objects, they are compacted to one end of the heap, eliminating fragmentation without needing a second memory region.

Generational

New objects are placed in the young generation, which uses the fast copying algorithm; objects surviving several collections are promoted to the old generation, which uses the mark‑compact algorithm.

1.2 Difference Between Copying and Mark‑Compact

The copying algorithm trades space for speed (scavenge), copying each live object as it is discovered, requiring extra memory; the mark‑compact algorithm separates marking and compaction phases, using time to save space, and can compact within a single heap region.

2. Dalvik Virtual Machine

2.1 Java Heap

The Java heap consists of an Active heap and a Zygote heap. The Zygote heap holds pre‑loaded classes and resources; the Active heap is used for runtime allocations after the Zygote process forks the app process. A copy‑on‑write (COW) strategy shares the heap until a write occurs, then copies the affected pages.

2.2 GC‑Related Metrics

Key metrics include Starting Size (-Xms), Maximum Size (-Xmx), and Growth Limit (-XX:HeapGrowthLimit). Additional metrics such as Min Free, Max Free, and Target Utilization guide the heap’s ideal size after each GC.

Starting Size: Initial heap size allocated at VM startup.

Growth Limit: Maximum heap size allowed per app; exceeding it causes OOM.

Maximum Size: Uncontrolled maximum heap size, e.g., when using the largeHeap attribute.

2.3 Types of GC

GC_FOR_MALLOC: Triggered when allocation fails due to insufficient memory.

GC_CONCURRENT: Triggered when the heap reaches a threshold, running concurrently.

GC_EXPLICIT: Triggered by System.gc, VMRuntime.gc, or SIGUSR1.

GC_BEFORE_OOM: Final GC attempt before throwing an OOM exception.

2.4 Object Allocation and GC Trigger Timing

Call dvmHeapSourceAlloc to allocate memory; if successful, return the address.

If allocation fails, check if a GC is already running; if so, wait for it to finish, otherwise invoke gcForMalloc (soft references not reclaimed).

After GC, retry dvmHeapSourceAlloc.

If still failing, grow the heap to the maximum size using dvmHeapSourceAllocAndGrow.

If that succeeds, return the address.

If it still fails, invoke gcForMalloc with soft‑reference reclamation.

Finally, retry dvmHeapSourceAllocAndGrow as a last attempt.

The flow shows that a failed allocation first triggers a GC_FOR_MALLOC without soft‑reference reclamation; if it still fails, a GC_BEFORE_OOM with soft‑reference reclamation occurs. After a successful allocation, the VM checks whether usage exceeds the GC_CONCURRENT threshold to possibly trigger a concurrent GC.

2.5 Reclamation Algorithms and Memory Fragmentation

Most Dalvik builds use Mark‑and‑Sweep; some include a copying GC compiled with the WITH_COPYING_GC flag. Mark‑and‑Sweep can cause fragmentation, leading to frequent GC when many small allocations are followed by a large one, as illustrated by the image below.

Therefore, on Dalvik devices, developers should minimize temporary short‑lived objects (e.g., in getView or onDraw) and avoid creating many long‑lived large objects.

3. ART Memory Reclamation Mechanism

3.1 Java Heap

ART’s heap consists of Image Space, Zygote Space, Allocation Space, and Large Object Space (LOS). Image Space holds pre‑loaded classes; Zygote and Allocation spaces correspond to Dalvik’s Zygote and Active heaps. LOS stores large objects (e.g., bitmaps) to improve GC efficiency.

3.2 Types of GC

kGcCauseForAlloc: Stop‑the‑world GC triggered by insufficient memory during allocation.

kGcCauseBackground: Background GC triggered when memory reaches a threshold, without stopping the world.

kGcCauseExplicit: Explicit GC invoked by the app (e.g., System.gc) when the option is enabled.

Other causes exist as well.

3.3 Object Allocation and GC Trigger Timing

The allocation process in ART is essentially the same as Dalvik; a diagram illustrates the steps.

3.4 Concurrent and Non‑Concurrent GC

ART selects different algorithms based on the situation. When memory is insufficient, a non‑concurrent (stop‑the‑world) GC runs; when usage crosses a threshold, a concurrent GC runs. The strategies differ between foreground and background execution.

Non‑Concurrent GC

Step 1: InitializePhase. Step 2: Suspend all ART threads. Step 3: MarkingPhase. Step 4: ReclaimPhase. Step 5: Resume threads. Step 6: FinishPhase.

Concurrent GC

Step 1: InitializePhase. Step 2: Acquire heap lock. Step 3: MarkingPhase (parallel). Step 4: Release heap lock. Step 5: Suspend all threads. Step 6: HandleDirtyObjectsPhase. Step 7: Resume threads. Step 8‑10: Repeat handling dirty objects, acquire lock, ReclaimPhase. Step 11: Release lock. Step 12: FinishPhase.

Both modes cause stop‑the‑world pauses, but concurrent GC shortens each pause.

3.5 Differences Between ART and Dalvik Concurrent GC

Dalvik GC:

ART GC:

ART offers three advantages: (1) Mark‑self – newly allocated objects are pushed onto an allocation stack, reducing traversal scope. (2) Prefetch – while marking, the VM pre‑loads upcoming objects and pushes their references onto the stack. (3) Reduced pause time – the Mark phase runs without blocking other threads, handling dirty data early and shortening the final stop‑the‑world phase.

3.6 Foreground and Background GC

Foreground GC runs while the app is visible and must be fast to preserve responsiveness; Mark‑Sweep is suitable. Background GC runs when the app is in the background, where pause time is less critical; Mark‑Compact can be used to defragment the heap.

3.7 ART Advantages

Overall, ART provides better GC efficiency (2‑3× faster), reduces pause times, offers a dedicated Large Object Space, and performs background heap compaction, greatly mitigating GC‑induced stutter. Google reports a ten‑fold improvement in allocation efficiency compared to Dalvik.

4. GC Log

4.1 Dalvik GC Log

Typical Dalvik log format:

D/dalvikvm: <GC_Reason> <Amount_freed>, <Heap_stats>, <Pause_time>, <Total_time>

gc_reason: Reason such as GC_ALLOC or GC_CONCURRENT.

amount_freed: Memory reclaimed by this GC.

Heap_stats: Current free and used heap ratios.

Pause_time: Duration the app was paused (stop‑the‑world).

Total_time: Overall time spent in the GC cycle.

4.2 ART GC Log

I/art: <GC_Reason> <Amount_freed>, <LOS_Space_Status>, <Heap_stats>, <Pause_time>, <Total_time>

In addition to the Dalvik fields, ART logs include LOS_Space_Status, which reports the usage of the Large Object Space for big allocations like bitmaps.

memory managementAndroidARTgarbage collectionDalvik
Tencent TDS Service
Written by

Tencent TDS Service

TDS Service offers client and web front‑end developers and operators an intelligent low‑code platform, cross‑platform development framework, universal release platform, runtime container engine, monitoring and analysis platform, and a security‑privacy compliance suite.

0 followers
Reader feedback

How this landed with the community

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.