垃圾回收相关算法
作者:互联网
垃圾回收相关算法
判断对象存活一般有两种方式:引用计数算法和可达性分析算法。
标记阶段:引用计数算法
举例对象A,被引用了计数器就+1,某个引用失效,计数器就-1,计数器为0就可以认为A对象不再被使用,可进行回收。
优点:实现简单、判定效率高,回收无延迟;
缺点:需要单独的字段存储计数器,并且无法处理循环引用,有内存泄漏的风险(致命缺陷)。
标记阶段:可达性分析算法
简单来说,就是被根对象集合直接或间接连接的对象才是存活对象,其他都是垃圾。
GC Roots根节点具体指:除了堆空间外的一些结构,比如虚拟机栈、本地方法栈、方法区、字符串常量池等地方对堆空间的引用,还有一些“临时性”地加入地对象。
可达性分析必须在一致性快照中进行,所以GC时必须“Stop The World”
清除阶段:标记-清除算法
- 先标记,收集器Collector从引用根节点开始遍历,标记所有被引用的对象(注意,不是标记垃圾)。
- 再清除,收集器Collector从头到尾进行线性遍历,将没有标记的对象回收。
这里的清除,只是把需要清除的对象地址保存在空闲列表中,用于新对象地址的覆盖。用空闲列表而不是指针碰撞的原因是内存不规整。
缺点:效率不高;GC的时候要STW,用户体验差;内存碎片问题,而且需要维护一个空闲列表。
清除阶段:复制算法
将内存空间分成两块,每次只使用一块。垃圾回收的时候,复制存活对象到另一块内存中,之后清除原内存区域的所有对象,最后交换两个内存块。
优点:没有标记和清除的遍历操作,高效;存活的对象空间连续,无内存碎片。
缺点:内存开销大;复制需要维护两个内存区对象的引用关系,时间开销也很大。
所以复制算法只适合存活对象少的,比如Eden区。
清除阶段:标记-整理算法
第一阶段和标记清理算法一样,标记所有被引对象;
第二阶段将所有存活对象压缩到内存的一端,按序排放,最后清除边界所有的空间。
优点:减小了标记清除算法的维护空闲列表的开销,和复制算法需要一倍空间的开销;
缺点:效率肯定不如复制算法;移动对象时需要考虑引用地址的调整;移动需要STW。
小结
标记清除 | 标记整理 | 复制 | |
---|---|---|---|
速率 | 中等 | 最慢 | 最快 |
空间开销 | 少(但会堆积碎片) | 少(不堆积碎片) | 通常需要活对象的2倍空间(不堆积碎片) |
移动对象 | 否 | 是 | 是 |
分代收集算法
根据新生代和老年代存活对象数量及回收频率的不同,年轻代采用复制算法,老年代采用标记-清除和标记-整理的混合实现。
增量收集算法
上述所有算法,在垃圾回收过程中,应用软件都会处在STW状态。增量收集算法就是让垃圾回收线程和应用程序线程交替进行
缺点:线程切换和上下文转换的消耗,使得垃圾回收成本上升,系统吞吐量下降。
分区算法
将内存区域分割成多个小块,每一个小区间都可独立使用,独立回收。
标签:标记,对象,清除,回收,算法,内存,垃圾 来源: https://www.cnblogs.com/reex/p/16519621.html