《深入理解Java虚拟机》读书笔记(JVM常识汇总二)

《深入理解Java虚拟机》强烈推荐。
垃圾收集算法:

1、标记清除算法:最基础的算法。“标记-清除(Mark-Sweep)”,分为标记和清除阶段,首先要标记需要被回收的对象,(第一张图上黑色部分即为被标记的对象),在标记完成后统一回收所有被标记的对象。 (第二张图即为回收后的内存图) 。它的主要不足: 1、 效率问题。标记和清除这2个过程效率都不高 2、空间问题,标记清除过程结束后会产生大量不连续的内存碎片,空间碎片太多会导致以后程序运行过程中需要分配大对象时候,无法找到足够大的连续的内存而不得不提前触发另一次垃圾收集动作。

2、复制算法(Copying): 为了解决效率问题,它将可用内存按容量分为大小相等的两块, 每次只使用其中的一块,当这一块的内存使用完了,(即被存活对象和可回收对象占满了),就将还存活对象复制到另一块空着的内存上去,然后将当前这块内存清空,这样就做到了每次回收只是对整个半区进行回收,实现简单,并且高效。但是代价是将可用的内存缩小为了原来的一半。 

在堆内存的新生代部分一般使用 复制算法。 因为新生代的对象一般都是存活时间比较短的,所以新生代划分为1个Eden和2个Survivor ,每次使用 Eden 和 1个Survivor ,当进行回收时,会把Eden 和Survivor 上存活的对象复制到另一块没有使用的Survivor上,然后清理掉刚才使用的Eden 和Survivor空间。eden和survivor的比例是8:1:1 ,所以每次可以使用的新生代中的内存为整个新生代内存的90%。有10%的内存就会被“晾着”,等待着那2块空间将存活对象复制。但是,如果某次回收对象时候,存活的对象大于那空闲survivor区的10%呢,放不下该咋办?这时,就需要依赖其他内存(这里指老年代)进行分配担保。




3、标记-整理算法(Mark-Compact):
              如果是标记-清除算法的话,效率会低,而复制算法则每次只能使用一半 的内存,还需要额外的空间进行分配担保。所以就有了“标记-整理”算法,它的思路和“标记-清除”算法是一样的,但是后续步骤不是直接清理可回收对象,而是让所有存活的对象都向一端移动,然后清理掉端边界之外的内存。这样就不会有碎片太多的问题。


               
4、 之前提到当代虚拟机一般都将Java堆分为新生代和老年代。 根据各个年代的特点,可以更方便的采用对应的算法进行垃圾回收,新生代中,每次都有大批对象死去,只有少量存活,所以一般采用复制算法。 而老年代中因为对象存活率较高,没有额外的空间给它进行分配担保,所以必须使用“标记-清除”或者“标记-整理”算法来进行回收。

猜你喜欢

转载自blog.csdn.net/Akanarika520/article/details/83384379
今日推荐