标记-清除算法
思想
标记-清除算法分为两个阶段:
- 标记阶段:标记出所有需要被回收的对象
- 清除阶段:回收被标记的对象所占用的空间
缺点
标记和清除两个阶段效室都不高:容易产生内存碎片,碎片太多可能会导致后续过程中需要为大对象分配空间时无法找到足够的空间而提前触发新的一次垃圾收集动作。
复制算法
思想
它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还在活着的对象复制到另外一块上面,然后再把已使用的内存空间一次清理掉。
优点
这种算法虽然实现简单,运行高效且不容易产生内存碎片
缺点
对内存空间的使用做出了高星的代价,因为能够使用的内存缩减到原来的一半。很显然,Copying 算法的效率跟存活对象的数目多少有很大的关系,如果存活对象很多,那么 Copying 算法的效率将会大大降低。
优化扬弃
因为新生代中的对象 98%是“朝生夕死”的,所以并不需要按照1:1的比例来划分内存空间。而是将内存分为一块较大的 eden 空间和2块较少的 survivor 空间,每次使用eden 和其中一块 survivor,当回收时将 eden 和 survivor还存活的对象一次性拷贝到另外一块 survivor 空间上,然后清理掉 eden 和用过的 survivor。 Oracle HotSpot 虚拟机默认 eden 和survivor 的大小比例是8:2,也就是每次只有10%的内存是“浪费”的。
什么是8:1:1GC 是统计学测算出内存使用超过98%以上时,内存应该被 minor gc时回收一次。但实际应用中,我们不能较真的只给他们留下2%,换句话说当内存使用达到 98%时才GC 就有点晚了,应该是多一些预留 10%内存空间。可以通过参数改变:-XX:SurvivorRatio:年轻代中 Eden 区与单个 Survivor 区的大小比值。
标记-整理算法
该算法标记阶段和标记-消除一样,但是在完成标记之后,它不是直接清理可回收对象,而是将存活对象都向一端移动,然后清理拉端边界以外的内在。
分代收集算法
一般是把堆分新生代和老年代;这样就可以根据不同的分区的特点使用不同的分区算法。
- 新生代中,每次都会发现大批量的对象死去,只有少量存活,那就用复制算法,只需要付出少量的复制成本就可以成收集
- 老年代存活率比较高、没有额外的存储空间进行担保,则使用“标记-清理”或“标记-签理”算法行回收。