Dalvik 虚拟机的垃圾收集简介

  1. 云栖社区>
  2. 博客>
  3. 正文

Dalvik 虚拟机的垃圾收集简介

铁锚 2017-01-26 20:51:00 浏览359
展开阅读全文

首先, Dalvik虚拟机比其他Java虚拟机中的垃圾收集要简单一些, 因为没有进行内存整理(no compacting). 也就是说堆内存中的对象在创建之后其地址永远都不会发生改变, 使得虚拟机其余部分的实现变得相对简单。

而GC会在 分配失败时触发, 包括以下情况:

  1. 触发 OutOfMemoryError 时,
  2. 堆内存的大小到达某些软限制时,
  3. 显式地请求GC时。

每种情况都有相应的标准来标识是否是 partial GC(部分GC, 只回收 active heap), 是否是 concurrent GC (并发GC, 在应用线程运行时执行大部分的对象标记任务), 以及是否是 preserving GC (保留GC, 保留软引用)。

典型的GC是由于内存限制所引起的, 只清理活跃堆,并发型和保留型的GC. 另一种触发GC的原因是 OutOfMemoryException, 是同步的,非保留式的(non-preserving)。

当前(Android 4.x) 使用的是 Mark-Sweep algorithm(标记清除)算法。

Mark-Sweep Algorithm(标记-清除算法)的处理过程

标记和清除算法是编程界第一种能够回收 循环数据结构 的算法。

使用标记-清除算法时, 未引用的对象不会立刻回收。相反,垃圾可以堆积, 直到耗尽所有可用内存。当内存不足时, 程序被暂停执行, 然后标记-清除算法清理所有的垃圾. 当所有未引用的对象被回收后, 再恢复程序的正常运行。

标记-清除算法被称为 ** tracing 垃圾收集器, 因为其追朔( traces out) 所有直接或间接被程序访问的对象。 程序可以直接访问的对象包括: 处理器栈上的局部变量引用的对象, 以及静态变量所引用的对象。 在GC的上下文中, 这些变量被称为 GC根(root)。 间接可访问是指由(直接/间接)对象所引用的对象。可访问对象也被称为 存活对象. 相反, 不再存活的对象就是垃圾。

标记-清除算法分为 两个阶段:

第一阶段,找到所有的可访问对象并标记, 称为 mark 阶段。

第二阶段, 垃圾收集算法扫描整个堆, 并回收所有未标记的对象, 称为sweep阶段。

02_01_mark-and-sweep.png

(a) 显示了垃圾收集之前的情况。在此示例中,只有单个 root 变量。

(b) 显示了 mark 阶段结束时的结果。此时, 所有的存活对象都被标记了。

(c) 显示了 sweep 阶段完成后留下的对象。只有存活对象留在内存中, 所有对象的 marked 字段再次被设置为false。

当然,到 Android5.0 以后, ART GC 的优化改进了Dalvik 虚拟机的很多性能瓶颈; 详情请参考: Android 5.0 ART GC 对比 Android 4.x Dalvik GC

此文也比较好: Android GC 从dalvik到ART的改进分析

原文链接: https://medium.com/@nitinkumargove/how-garbage-collection-works-in-dalvik-vm-in-android-bf781ab48531

翻译人员: 铁锚 http://blog.csdn.net/renfufei

翻译时间: 2017年01月26日

网友评论

登录后评论
0/500
评论
铁锚
+ 关注