Minor GCFull GC是Java虚拟机(JVM)中用于回收不再使用对象内存的两种垃圾回收(GC)过程。在区分不同垃圾回收方式之前,我们需要先了解一下Java内存区域的划分。在Java堆区中,内存被分为以下几个部分:

  1. 年轻代 (Young Generation): 这部分内存用于新生成的对象。大部分对象都是朝生夕死的,因此年轻代经常发生垃圾回收,即Minor GC。它通常被进一步细分为三个区域:

    • Eden区: 所有新创建的对象首先被分配到这里。

    • 两个Survivor区(S0和S1): 存活下来的对象会从Eden区移动到一个Survivor区,然后在Survivor区之间来回复制,随着次数的增加,最终如果对象还存活,它们会被移动到老年代。

  2. 老年代 (Old or Tenured Generation): 在年轻代中经过一定数量Minor GC仍然存活的对象会被移动到老年代。这部分内存的回收频率低于年轻代,因为假设这里的对象生命周期较长。触发老年代的GC,即Full GC,会对系统性能产生较大影响。

  3. 元空间 (Metaspace): 在JDK 8及以后的版本中,永久代(PermGen)已经被元空间所取代。元空间并不在堆内存中,而是使用本地内存。JVM将类的元数据放置在这个空间里,如类的定义信息等。Metaspace的大小只受到系统可用内存的限制。

触发Minor GC的情况:

Minor GC主要发生在年轻代。以下情况会触发Minor GC:

  1. 应用程序新创建对象:当应用程序继续创建新对象,并且年轻代的Eden区域填满时,JVM会触发Minor GC来清除那些无法达到生存条件的对象(通常是没有引用的对象)。

  2. Survivor空间不足:在Eden区进行过Minor GC后,存活下来的对象会被移动到Survivor空间(S0和S1)。如果Survivor空间容纳不下这些存活的对象,一些对象可能会直接晋升至老年代,如果连续多次GC后仍然存活的对象也会被移动到老年代。

触发Full GC的情况:

Full GC是一个更全面的垃圾回收过程,它包括了对年轻代、老年代和元空间(或永久代)的清理。以下情况常见触发Full GC:

  1. 老年代空间不足当老年代几乎满时,JVM会尝试进行Full GC来清理老年代中的无用对象。

  2. 方法区或元空间不足:如果运行时常量池需要更多的内存,而方法区或元空间无法提供时,会触发Full GC尝试回收这些区域的内存。

  3. System.gc()调用:如果系统代码中调用了System.gc(),而JVM参数没有设置忽略显式GC调用,则JVM可能执行Full GC。

  4. 大对象直接分配在老年代:对于较大的对象,JVM可能直接在老年代分配内存,如果老年代空间不足,可能触发Full GC。

  5. JVM内部诊断:JVM进行某些内部诊断任务时,如果发现空间不足,可能也会触发Full GC。

  6. 年轻代晋升策略:JVM中有配置参数决定了对象从年轻代晋升到老年代的阈值,如果超过这个阈值,会触发Full GC。

  7. 其他因素:比如老年代中大量碎片化导致无法找到足够的连续空间来分配大对象,即使总体上有空间。

每种垃圾回收器都有自己的策略和场景,例如G1 GC旨在通过适时的Mixed GC来避免Full GC的长时间停顿,而ZGC和Shenandoah则采用更先进的并发收集技术来最小化STW(Stop-The-World)事件。

了解何时会触发Minor GC和Full GC对于性能优化和系统稳定性非常重要,因此开发人员和性能调优工程师经常需要监控GC日志和使用各种监控工具来分析垃圾回收行为。

本篇文章来源于微信公众号: 互联网面试小帮手



微信扫描下方的二维码阅读本文

此作者没有提供个人介绍
最后更新于 2024-04-26