垃圾收集算法

标记-清除算法:

效率不高,会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分派较大对象时,无法找到足够的连续内存而不得不提前出发另一次垃圾收集动作。图片引用自《深入JVM》

垃圾收集算法

复制算法:

将内存按容量分为大小相等的两块,每次只使用其中的一块,当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这样解决了效率问题,但是代价是将内存缩小为了原来的一半,代价太高。研究表明,新生代中的对象98%是“朝生夕死”的,所以并不需要按照1:1的比例来划分内存空间,而是将内存分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden和Survivir中的一块。当回收时,将Eden和Survivor中还存活着的对象一次性地复制到另外一块Survivor空间上,最后清理掉Eden和刚才用过的Survivor空间。HopSpot虚拟机默认的Eden和Survivor的大小比例是8:1,也就是每次新生代中可用内存空间为整个新生代容量的90%,只有10%的内存会被“浪费”。当然,98%的对象回收只是一般场景下的数据,我们没办法保证每次回收都只有不多于10%的对象存活,当Survivor空间不够用时,需要依赖其他内存(这里指老年代)进行分配担保。

垃圾收集算法


标记-整理算法:

和标记-清除算法一样,但是后续不走不是直接对可回收对象进行清理,而是让所有存活对象都向一端移动,然后直接清理掉边界以外的内存。

垃圾收集算法



分代收集算法:

将堆划分为新生代和老年代,根据各自不同的特点采用不同的算法。新生代一般采用复制算法,老年代一般采用标记-清除/整理。当代商业虚拟机都采用分代收集算法。