这是我参与更文挑战的第 22 天,活动详情查看: 更文挑战
垃圾回收清除阶段相关算法
1.标记-清除算法
从标记阶段区分出存活对象和死亡对象后,GC接下来就是执行垃圾回收,释放死亡对象所占用的内存。
目前JVM主要有三种常见的垃圾收集算法有:
- 标记-清除算法
- 复制算法
- 标记-压缩算法
标记-清除算法是一种非常基础和常见的垃圾收集算法。
执行过程:当堆中有效内存被耗尽的时候,会停止整个程序,也即Stop the world(STW),然后开始两个工作,分别是标记和清除:
- 标记:Collector从引用根点开始递归遍历,**标记所有被引用的对象,**在对象的Header中记录为可达对象。
- 清除:Collector对堆内存从头到尾进行线性遍历,如果发现某个对象在Header中没有被标记为可达对象,则将其回收。
缺点:
- 效率一般,因为标记和清除都需要遍历,所有效率较慢。
- GC的时候会触发STW,用户体验差。
- 这种方式清除来的内存是不连续的,产生内存碎片,需要维护一个空闲列表。
关于清除的说明:所谓的清除并不是真的置空,而是把需要清除的对象地址保存在空闲列表。有新的对象加载时,判断垃圾的空间释放足够,如果足够就直接覆盖存放。
2.复制算法
概述:
复制算法主要为了解决标记-清除算法的弊端。其核心思想是将活着的内存空间分成两块,每次只使用一块,在垃圾回收时将正在使用的内存中存活的对象复制到未被使用的内存块中,最后清除正在使用的内存块,交换两个内存的角色,最后完成垃圾回收。
优点:
- 没有标记和清除的过程,实现简单,运行高效。
- 复制过去的内存保证空间连续性,不会有碎片问题。
缺点:
- 需要两倍的内存空间。
- 如果对象移动,那么需要修改栈空间的引用地址。参考: 对象访问定位
注意:如果系统中的存活对象多,而复制算法复制的存活对象数量并不会太大,所以效率会非常低。而在新生代的Survivor适合复制算法。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END