1.清除算法
- 1.1标记清除算法
首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象,
两个不足,一是标记和清除两个过程效率都不好,二是空间的问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能导致以后在程序运行过程中需要分配较大的对象,无法找到足够的连续内存而不得不提前出发另一次垃圾收集动作
- 1.2复制算法
他将可用内存按容量划分为大小相等的两块,然后再把已使用过的内存依次清除掉只要移动堆顶的指针,按顺序分配内存,实现简单高效。只是这种算法的代价是将内存缩小为原来的一半,未免太高了,可以使用新生代对象“朝生夕死”
新生代复制算法不是1:1 默认eden和survivor的大小比例是8:1 只有10%浪费。
- 1.3标记整理算法
标记过程仍然与标记清除算法一样,但后续步骤不是直接对可回收对象进行清理而是让所有存活的对象都向一端移动,然后直接清理掉端边以外的内存
新生代大批对象死去少量存活,那只需要付出少量存活对象的复制成本就可以完成收集 选用复制算法
老年代对象存活率搞、没有而外空间对他进行担保,就必须使用 标记清理或者编辑整理算法进行回收
枚举根节点:我们可以在某个位置把栈上代表引用的位置记录下来,这样在gc发生的时候就不用全部扫描了,在HotSpot中使用的是一种叫做OopMap的数据结构来记录的。对于OopMap可以简单的理解是存放调试信息的对象。
栈中只有一部分数据是Reference(引用)类型,那些非Reference的类型的数据对于找到根节点没有什么用处
2.安全点
安全点:在特定位置记录这些信息(Oopmap),这些位置称为安全点
循环的末尾
方法临返回前/调用方法的call指令后
可能抛异常的位置
安全区域:安全点机制保证了程序执行时,在不太长时间内就会遇到可进入的Safepoint。但程序不执行的时候,比如线程sleep或者lock,安全区域是指在一端代码片段之中,引用关系不会发生变化,在这个区域中的任意地方开始GC都是安全的,也可以把safe Reginon看做是扩展的Safepoint