JVM学习之垃圾收集算法

版权声明:本文为博主原创文章,转载希望能注明出处,感谢。 https://blog.csdn.net/u010126792/article/details/82992013

以下blog内容来自《深入理解Java虚拟机_JVM高级特性与最佳实践》,感谢作者!

昨天下班后地铁上和以前的同学交谈,才知道永远不尝试新东西永远不会有新思路,希望写完基础系列之后自己能有所进步,然后分析更多有用的东西。

1垃圾收集算法分类

       垃圾收集算法是如何收集对象,也就是如何回收堆及其他被jvm管理的可回收的内存的算法,和书中一样这里只按照书本记录垃圾收集算法的思路。

垃圾收集算法:

标记-清除算法,复制算法,标记整理算法,分代收集算法。

2 标记清除算法

是最基础的垃圾收集算法,之后的算法都是在此基础上的改进,标记-清除算法分成两个阶段,标记和清除;

过程:标记出所有需要回收的对象,标记完成后统一回收所有被标记的对象(怎么判断应该被回收请看)。

存在的问题:

(1)效率不高,标记和清除两个过程效率都不高,

(2)空间问题,标记清除后会产生大量不连续的内存碎片(当需要分配大对象时,不连续的内存空间无法使用造成浪费)。

借用书中图:

                                                      

3 复制算法

      复制算法为解决标记清除算法的效率问题,该算法将可用内存划分成大小相同的两块,每次只使用其中一块。

       具体过程首先用一块内存存储对象,当这块内存用完时就将还存活着的对象复制到另外一块上面,然后把已使用过的内存空间 一次清理掉。所以每次都是先把存活的对象复制到另外一块内存,然后直接清理掉当前的使用的块的全部内存,效率会更高,

                                                                                                                                           

缺点:

可以看到每次只能使用总内存的一半,所以这种算法比标记清除更浪费内存。

虽然浪费内存但当今使用的主流JVM的垃圾收集算法都是采用这种收集算法回收新生代,但并不是按照1:1的比例来划分内存(绝大多数对象朝生夕死),将内存划分成一块较大的Eden和两个较小的Survivor空间,每次使用Eden和其中的一块Survivor,回收时将Eden和Survivor中还存活的对象一次性复制到另外一个Survivor空间上,之后清理掉Eden和上次使用的Survivor(默认每次存活对象较少,否则可能造成内存不够用,之后需要额外的空间进行分配担保)。

4 标记-整理算法

复制算法在存活对象较多时效率会降低,浪费的内存也会更多,所以老年代不适合这种算法(老年代存活对象较多)。

标记-整理算法符合老年代的特点,也是首先进行标记,之后不是直接清除而是让所有存活对象向一端移动,这样就不会存在内存碎片,最后清理掉端边界以外的内存。

                                                                              

5分代收集算法

分代收集算法把内存划分成新生代和老年代,新生代对象存活较少,老年代存活对象较多,所以两个区域采用不同的垃圾收集算法,新生代利用复制算法,老年代利用标记-整理或者标记-清除算法进行对象回收。

猜你喜欢

转载自blog.csdn.net/u010126792/article/details/82992013
今日推荐