垃圾回收算法-通用的分代垃圾回收机制

发布时间 2023-12-30 17:13:57作者: 欢乐豆123

垃圾回收算法-通用的分代垃圾回收机制

    概要

    分代垃圾回收机制,是基于这样一个事实:不同对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的回收算法,以便提高回收效率。

    我们将对象分为三种状态:年轻代、年老代、永久代。同时,将处于不同状态的对象放到堆中不同的区域。

    一、年轻代
    所有新生成的对象首先都是放在Eden区。年轻代的目标就是尽可能快速的收集到那些生命周期短的对象,对应的是Minor GC,每次Minor GC会清理年轻代的内存
算法用效率较高的复制算法,频发的操作,但是会浪费内存空间,当“年轻代”区域存放满对象后,就将对象存放到年老代区域。

   二、年老代
   在年轻代中经历了N(默认15)次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。年老代对象越来越
多,我们就需要启动Major GC和Full GC(全量回收),来一次大扫除,全面清理年轻代区域和年老代区域。

   三、永久代
   用于存放静态文件,如Java类、方法等。永久代对垃圾回收没有显著影响。JDK7以前就是“方法区”的一种实现。JDK8以后已经没有"永久代”了,使用metaspace
元数据空间和堆替代

  四、垃圾回收算法

   1.  Minor GC:
   用于清理年轻代区域。Eden区满了就会触发一次Minor GC。清理无用对象,将有用对象复制到"Survivor1”、"Survivor2”区中。

   2. Major GC:
  用于清理老年代区域。

   3. Full GC:
  用于清理年轻代、年老代区域。成本较高,会对系统性能产生影响。

   Eden区:存储了从未通过垃圾回收的新对象
   Survivor区:存放垃圾回收后,仍然有用的对象。循环存放,小于15次垃圾回收次数
   Tenured区:年老代区域存放超过15次垃圾回收的对象。

  五、JVM调优和Full GC

  在对M调优的过程中,很大一部分工作就是对于Full GC的调节。有如下原因可能导致Full GC:
  1.  年老代(Tenured)被写满
  2. 永久代(Perm)被写满
  3. System.gc()被显式调用(相当于建议,能不能被调用由系统决定)
  4. 上一次GC之后Heap的各域分配策略动态变化