Java中常用的垃圾回收算法

如何确定垃圾

Java中采用可达性分析算法来确定对象是否应该被回收,可达性分析算法通过一系列的GC Roots的点作为起点向下搜索,GC Roots主要包括栈中的引用(当前正在调用的方法中局部变量的引用)、方法区中静态变量和常量的引用、本地方法栈中的引用。当一个对象到任意GC Roots都没有引用链的时候证明该对象可以回收。

标记-清除算法(内存碎片多)

标记-清除法首先会标记可回收的对象,在清理完对象后,并没有重新整理可用的内存空间,如果内存中回收的小对象比较多,会引起内存碎片化的问题,后期大对象则无法获取连续可用的内存空间,而年轻代GC的时候,会有大量的对象需要回收,需要标记的回收对象比较多,效率低,内存碎片也比较多,所以不适合年轻代GC。而老年代GC的时候,需要回收的对象少,标记的对象也就比较少,所以适用于老年代GC。

复制法(占用更多的内存空间)

复制法首先将内存划分为大小相同的两份,然后将存活的对象复制一份放入到第二份内存区域中,然后直接删除第一份内存区域。年轻代GC的时候,存活的对象比较少,需要回收的对象多,所以可以使用复制法;而老年代GC的时候存活的对象多,需要复制的对象就比较多,来回复制较多的对象会影响运行效率,所以复制法不适合老年代GC。

标记-整理法(占用空间少,无内存碎片)

标记-整理法结合了复制法和标记-清除法的优点,首先标记可回收的对象,然后将存活的对象移动到内存的另一端,然后清除该端的对象,释放内存,适用于老年代GC。

分代收集法

分代收集法不是固定的算法,而是一种思想,它将不同类型的对象采用不同的垃圾回收算法。JVM将堆划分为年轻代、老年代、永久代。

  • 年轻代使用复制法,将少量存活的对象复制到另一份内存区域中,然后清除掉原来的内存区域
  • 老年代和永久代使用标记-清除法或标记-整理法,其中永久代主要回收废弃的常量和无用的类,老年代主要存放长生命周期的对象和大对象,可回收的对象少。标记-清除法将可回收的对象进行标记,然后删除带标记的对象,如果是标记-整理法,还会将存活的对象移动到内存的另一端进行整理,避免内存碎片问题。

猜你喜欢

转载自blog.csdn.net/qq_36986015/article/details/113754282
今日推荐