Android垃圾回收机制详解
近来在深挖Android的垃圾回收机制,发现这方面原本数量少得可怜的技术文章却大多早已过时,无奈下只好多方查阅资料,现在我就了解到的情况做一个总结,希望对你有所帮助,如有错误欢迎在评论区指出。
前言
Android如今使用的虚拟机名叫Android Runtime,简称Art(本文后面将用Art来指代Android虚拟机),而Art的其中一大职责就是负责垃圾回收。
在讲述Art的垃圾回收机制之前,还需要了解Art如何判定一个对象是垃圾。
目前主流有两种判定算法,引用计数方法和可达性分析算法,Art采用的是第二种算法,由于引用计数方法不是本文的重点,下面我仅就可达性分析算法展开介绍。
下面的内容截取自《深入理解Java虚拟机的介绍》。
“当前主流的商用程序语言(Java、C#,上溯至前面提到的古老的Lisp)的内存管理子系统,都是 通过可达性分析(Reachability Analysis)算法来判定对象是否存活的。这个算法的基本思路就是通过 一系列称为“GC Roots”的根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过 程所走过的路径称为“引用链”(Reference Chain),如果某个对象到GC Roots间没有任何引用链相连, 或者用图论的话来说就是从GC Roots到这个对象不可达时,则证明此对象是不可能再被使用的。 如下图所示,对象object 5、object 6、object 7虽然互有关联,但是它们到GC Roots是不可达的, 因此它们将会被判定为可回收的对象。”
至于在Java技术体系里面,固定可作为GC Roots的对象有哪些的问题由于不是本文的重点这里就不再展开细讲,感兴趣的小伙伴可以自行查阅。
了解Art如何界定一个对象是垃圾后,我们再来看看它是如何进行垃圾清理的。
常见的垃圾清理算法有三种,标记-清除算法,标记-复制算法,标记-整理算法。
不同于Dalvik(Android上一代虚拟机)只采用了一种算法的是,Art采用了两种算法,标记-复制算法,标记-整理算法,下面先简单介绍标记-复制法。
下面内容截取自《深入理解Java虚拟机的介绍》。
“标记-复制算法常被简称为复制算法。为了解决标记-清除算法面对大量可回收对象时执行效率低的问题,1969年Fenichel提出了一种称为“半区复制”(Semispace Copying)的垃圾收集算法,它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。如果内存中多数对象都是存活的,这种算法将会产生大量的内存间复制的开销,但对于多数对象都是可回收的情况,算法需要复制的就是占少数的存活对象,而且每次都是针对整个半区进行内存回收,分配内存时也就不用考虑有空间碎