【Java虚拟机】垃圾收集算法

版权声明:转载请注明出处: https://blog.csdn.net/qq_21687635/article/details/83856301

垃圾收集算法

标记 - 清除算法

算法分为两个阶段:标记和清除。首先标记出所有需要回收的对象,在标记完成后统一回收所有标记的对象。缺点是标记清除过后会产生大量不连续的碎片,空间碎片太多可能会导致以后再程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前出发另一次垃圾收集动作。

标记 - 清除算法如下图所示:
标记 - 清除算法

复制算法

将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。只是这种算法的代价是将内存缩小为了原来的一半。

复制算法如下图所示:
复制算法示意图
现在的虚拟机都采用这种算法来回收新生代,IBM公司的专门研究表明,新生代的对象98%是“朝生夕死”的,所以并不需要按照1:1的比例来划分内存空间,而是将内存分为一块大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中一块Survivor。当回收时,将Eden和Survivor还存活着的对象一次性地复制到另外一块Survivor空间上,最后清理掉Eden和刚才使用过的Survivor空间。

HotSpot虚拟机默认Eden和Survivor的大小比例是8:1,也就是每次新生代可用内存空间为整个新生代容量的90%,只有10%的内存会被“浪费”。当然,98%的对象可回收只是一般场景下的数据,我们没有办法保证每次回收都只有不多于10%的对象存活,当Survivor空间不够用时,需要依赖其他内存(这里指老年代)进行分配担保。

标记 - 整理算法

算法同样分为两个阶段:标记和整理。标记阶段与“标记 - 清除”中的一样,整理是让所有存活的对象都向一段移动,然后直接清理掉端边界以外的内存。

标记 - 整理算法如下图所示:
标记 - 整理算法示意图

分代收集算法

一般把Java堆分为新生代和老年代

  • 新生代采用复制算法
  • 老年代采用“标记 - 清除”或“标记 - 整理”算法

参考

  1. 深入理解Java虚拟机[书籍]

猜你喜欢

转载自blog.csdn.net/qq_21687635/article/details/83856301