JVM、Dalvik、ART垃圾回收机制
一、JVM垃圾回收机制(桌面/服务器端)
1. 核心算法:分代收集
-
新生代回收(Minor GC)
-
触发条件:Eden区满时触发
-
算法:复制算法(Eden → Survivor区)
-
过程:存活对象在Survivor区间复制,年龄+1;年龄超阈值(默认15)晋升老年代
-
-
老年代回收(Major GC/Full GC)
-
触发条件:老年代空间不足
-
算法:标记-清除(产生碎片)或标记-整理(无碎片)
-
耗时:10倍于Minor GC,导致应用暂停(STW)
-
2. 对象存活判定:可达性分析
-
GC Roots类型:
-
虚拟机栈局部变量
-
方法区静态变量与常量
-
JNI引用对象
-
-
解决循环引用:不可达对象判定为垃圾(对比引用计数法)
3. GC触发场景
二、Dalvik垃圾回收机制(Android 4.4及之前)
1. 核心设计:移动端适配
-
堆结构:
-
Zygote堆:预加载系统类(进程间共享)
-
Active堆:应用独享,对象分配主区域
-
-
回收算法:标记-清除(Mark-Sweep)
-
位图标记:独立空间记录对象状态,减少对象头开销
-
三次STW:
-
每次暂停约5-10ms,导致界面卡顿
-
-
2. 致命缺陷
-
全堆扫描:每次GC需遍历所有对象
-
内存碎片:清除后产生不连续空间,大对象分配失败
-
高功耗:频繁GC增加CPU负载
三、ART垃圾回收机制(Android 5.0+)
1. 革命性优化
2. 核心机制解析
-
并发标记清除(CMS):
-
标记阶段:
-
初始标记(STW暂停1次):标记根对象(耗时≤1ms)
-
并发标记:与应用线程并行遍历引用链
-
最终标记(非STW):处理引用变更(ModUnionTable记录脏数据)
-
-
清除阶段:后台线程异步回收
-
-
分代策略增强:
-
年轻代:复制算法(Minor GC <2ms)
-
老年代:标记-整理(避免碎片)
-
大对象直存老年代:避免年轻代频繁回收
-
3. GC触发条件
四、三大运行时GC机制对比
五、面试标准答案(背诵版)
Q:JVM、Dalvik与ART的GC核心区别?
A: 三者本质是不同场景的运行时环境,核心差异如下:
算法设计:
JVM:分代收集(新生代复制算法+老年代标记整理)
Dalvik:标记-清除(全堆扫描,三次STW卡顿严重)
ART:并发标记清除(CMS仅1次STW,增量清除减少卡顿)
堆结构:
JVM:新生代(Eden+Survivor)+老年代
Dalvik:Zygote堆(共享)+Active堆(进程独享)
ART:四空间划分(Image预加载类+Large Object专存大对象)
移动端优化:
Dalvik:写时复制共享系统类(节省内存)
ART:AOT预编译减少运行时开销,并发GC降低STW至1次
性能指标:
卡顿:ART(5ms)< Dalvik(30ms)< JVM Full GC(100ms+)
内存利用率:ART > JVM > Dalvik(碎片问题)128
Q:ART如何实现高效GC?
A: 四大关键技术:
并发标记:通过ModUnionTable记录引用变更,标记阶段仅需1次STW
增量清除:回收过程与应用线程并行
堆分区:Large Object Space隔离大对象,减少年轻代压力
AOT预编译:安装时生成机器码,减少运行时解释开销