一步一步学JVM

时间:2023-01-02 16:32:44

标记-清除算法

         算法分为标记和清除两个阶段:首先标记所有需要回收的对象,在标记完成后统一回收所有被标记的对象。

         该算法存在的缺点:

  1、  效率问题:标记和清除两个过程的效率都不高

  2、  空间问题:标记清除之后会产生大量不连续的内存碎片,内存碎片太多可能会倒是以后在程序运行过程中需要分配较大的对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾回收。

复制算法

         为了解决回收效率问题,引出了复制算法。它将可用内存按照容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活的对象复制到另外一块上面,然后把已经使用过的内存空间一次性清理掉。这样每次回收都对整个半区进行回收,不用考虑内存碎片的复杂情况,只需要移动堆指针,按顺序分配内存即可。

         缺点:

         这种算法的代价是将内存缩小为了原来的一半,浪费空间。

          关于复制算法的更详细讲解可以参考:聊聊JVM的年轻代

标记-整理算法

         复制算法对于在新生代这种对象存活率比较低的算法比较适合。但是对于老年代这种区域,效率会变低。所以在老年代中一般使用标记-整理算法

         标记-整理算法中的标记和标记-清理中的标记时一样的,但整理步骤不是对标记的对象直接进行清理,而是让所有存活的对象都向一端移动,然后清理掉边界以外的内存。

分代收集算法

         分代收集算法根据对象存活周期将内存划分为极快。一般是把Java的堆划分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代采用复制算法,在老年代采用“标记-清理”算法或者“标记-整理”算法进行回收。