JVM、Dalvik、ART垃圾回收机制

发布于:2025-07-24 ⋅ 阅读:(18) ⋅ 点赞:(0)

一、JVM垃圾回收机制(桌面/服务器端)

1. 核心算法:分代收集

  • 新生代回收(Minor GC)

    • 触发条件:Eden区满时触发

    • 算法:复制算法(Eden → Survivor区)

    • 过程:存活对象在Survivor区间复制,年龄+1;年龄超阈值(默认15)晋升老年代

  • 老年代回收(Major GC/Full GC)

    • 触发条件:老年代空间不足

    • 算法:标记-清除(产生碎片)或标记-整理(无碎片)

    • 耗时:10倍于Minor GC,导致应用暂停(STW)

2. 对象存活判定:可达性分析

  • GC Roots类型

    • 虚拟机栈局部变量

    • 方法区静态变量与常量

    • JNI引用对象

  • 解决循环引用:不可达对象判定为垃圾(对比引用计数法)

3. GC触发场景
GC类型 触发条件 影响范围
Minor GC Eden区满 仅新生代
Full GC 老年代满/调用System.gc() 全堆+方法区
MetaSpace GC 类元数据超限 元空间

二、Dalvik垃圾回收机制(Android 4.4及之前)

1. 核心设计:移动端适配
  • 堆结构

    • Zygote堆:预加载系统类(进程间共享)

    • Active堆:应用独享,对象分配主区域

  • 回收算法:标记-清除(Mark-Sweep)

    • 位图标记:独立空间记录对象状态,减少对象头开销

    • 三次STW

      • 每次暂停约5-10ms,导致界面卡顿

2. 致命缺陷
  • 全堆扫描:每次GC需遍历所有对象

  • 内存碎片:清除后产生不连续空间,大对象分配失败

  • 高功耗:频繁GC增加CPU负载


三、ART垃圾回收机制(Android 5.0+)

1. 革命性优化

2. 核心机制解析
  • 并发标记清除(CMS)

    • 标记阶段

      1. 初始标记(STW暂停1次):标记根对象(耗时≤1ms)

      2. 并发标记:与应用线程并行遍历引用链

      3. 最终标记(非STW):处理引用变更(ModUnionTable记录脏数据)

    • 清除阶段:后台线程异步回收

  • 分代策略增强

    • 年轻代:复制算法(Minor GC <2ms)

    • 老年代:标记-整理(避免碎片)

    • 大对象直存老年代:避免年轻代频繁回收

3. GC触发条件
GC原因 触发场景 线程影响
kGcCauseForAlloc 分配对象时内存不足 STW暂停
kGcCauseBackground 后台并发GC(堆使用达阈值) 无STW
kGcCauseExplicit 调用System.gc() STW暂停

四、三大运行时GC机制对比

维度 JVM Dalvik ART
堆结构 新生代+老年代+元空间 Zygote堆+Active堆 Image/Zygote/Allocation/Large Object Space
回收算法 分代收集(复制+标记整理) 标记-清除(全堆扫描) CMS(并发标记+增量清除)
STW暂停 Full GC时显著暂停 3次暂停/次GC 仅1次初始标记暂停
碎片处理 标记整理压缩 无优化(依赖Bionic) 在线内存压缩(ART 10+)
移动端优化 写时复制共享Zygote堆 AOT+JIT混合编译
典型GC耗时 Full GC:100ms+ 每次暂停5-10ms Minor GC:<2ms;Full GC:5-10ms

五、面试标准答案(背诵版)

Q:JVM、Dalvik与ART的GC核心区别?

A: 三者本质是不同场景的运行时环境,核心差异如下:

  1. 算法设计

    • JVM:分代收集(新生代复制算法+老年代标记整理)

    • Dalvik:标记-清除(全堆扫描,三次STW卡顿严重)

    • ART:并发标记清除(CMS仅1次STW,增量清除减少卡顿)

  2. 堆结构

    • JVM:新生代(Eden+Survivor)+老年代

    • Dalvik:Zygote堆(共享)+Active堆(进程独享)

    • ART:四空间划分(Image预加载类+Large Object专存大对象)

  3. 移动端优化

    • Dalvik:写时复制共享系统类(节省内存)

    • ART:AOT预编译减少运行时开销,并发GC降低STW至1次

  4. 性能指标

    • 卡顿:ART(5ms)< Dalvik(30ms)< JVM Full GC(100ms+)

    • 内存利用率:ART > JVM > Dalvik(碎片问题)128

Q:ART如何实现高效GC?

A: 四大关键技术:

  1. 并发标记:通过ModUnionTable记录引用变更,标记阶段仅需1次STW

  2. 增量清除:回收过程与应用线程并行

  3. 堆分区:Large Object Space隔离大对象,减少年轻代压力

  4. AOT预编译:安装时生成机器码,减少运行时解释开销


网站公告

今日签到

点亮在社区的每一天
去签到