说下JVM中一次完整的GC流程?

大家好,我是锋哥。今天分享关于【**说下JVM中一次完整的GC流程?】面试题。**希望对大家有帮助;

说下JVM中一次完整的GC流程?

1000道 互联网大厂Java工程师 精选面试题-Java资源分享网

在JVM中,垃圾回收(GC) 是自动化内存管理的一部分,用于回收不再被引用的对象,释放内存资源。JVM的GC主要通过标记、清除和压缩等算法来管理内存。GC的过程较为复杂,涉及多个阶段和多个垃圾回收器。下面是一次完整的垃圾回收流程的详细介绍。

1. GC触发条件

GC的触发条件有多个,主要包括:

  • 堆内存不足:当JVM中的堆内存(年轻代、老年代)不足时,会触发GC。
  • 显式调用System.gc():调用该方法会触发GC,但JVM不一定会立刻执行。
  • 内存分配失败:在分配内存时,如果不能从堆中找到足够的空间,也会触发GC。
  • 老年代的空间不足:年轻代的GC不足以回收老年代所需的空间时,会触发Full GC。

2. GC的分代理论

JVM的堆内存通常分为三个区域:

  • 年轻代(Young Generation) :包含新创建的对象。年轻代又分为三个区域:
    • Eden空间:新创建的对象首先会被分配到Eden区。
    • Survivor空间(S0, S1):Eden区存活下来的对象会被复制到其中一个Survivor空间。两个Survivor区交替使用。
  • 老年代(Old Generation):经过多次GC后仍然存活的对象会被提升到老年代。
  • 永久代(PermGen):用于存储类的元数据(JVM 8后被MetaSpace取代)。

3. GC的基本步骤

1) 年轻代GC(Minor GC)

年轻代GC发生在年轻代内存不足时,步骤如下:

  • 标记阶段
    • JVM首先会标记出年轻代中存活的对象。标记对象是通过引用计数可达性分析的方式确定的。
    • 在这个阶段,Root(如栈上的局部变量、静态变量等)会作为起始点,通过引用关系递归地遍历所有可达对象。
  • 复制阶段
    • 对象存活标记完成后,JVM会将存活的对象从Eden区复制到其中一个Survivor区。如果当前Survivor区已满,则会将对象转移到老年代。
    • 如果Survivor区的空间不足以容纳所有存活的对象,就会触发老年代GC(Full GC)。
  • 清理阶段
    • Eden区和原先的Survivor区会被清空,释放空间供新的对象使用。
2) 老年代GC(Major GC 或 Full GC)

老年代GC通常是在年轻代GC不能有效回收内存时发生,尤其是当老年代空间不足时触发。此时JVM会进行整个堆的垃圾回收:

  • 标记阶段
    • 对象的标记和年轻代GC相似,通过可达性分析标记存活对象。
  • 清理阶段
    • 清理所有未被标记的对象,释放内存空间。
  • 压缩阶段
    • 在老年代GC后,可能会进行内存压缩。即将存活的对象移到内存的一端,释放出连续的空闲内存。
3) GC算法

JVM中常用的GC算法包括:

  • 标记-清除(Mark-Sweep)
    • 标记所有存活的对象,然后清除未标记的对象。缺点是会产生内存碎片。
  • 复制算法(Copying)
    • 适用于年轻代的GC。将存活对象从一个区域复制到另一个区域,清空源区域,避免内存碎片。
  • 标记-整理(Mark-Compact)
    • 适用于老年代的GC。标记所有存活的对象并将其压缩到堆的一端,避免内存碎片。
  • 分代收集
    • 根据不同的对象生命周期,年轻代和老年代使用不同的GC算法来提高效率。年轻代采用复制算法,老年代采用标记-清除或标记-整理。

4. GC的执行过程

一个完整的GC过程可以分为以下几个步骤:

  1. GC Root Tracing:JVM会从GC Roots开始,通过引用链追踪可达的对象。
  2. 标记阶段:标记所有存活的对象,GC通过可达性分析找到所有从GC Root可达的对象。
  3. 清除阶段:对于未被标记的对象(即不可达的对象),会被清除。
  4. 压缩阶段(仅老年代GC时执行):将存活的对象移动到内存的一端,释放连续的空间。

5. GC类型

JVM有多种垃圾回收器,每个垃圾回收器的工作方式不同,常见的回收器包括:

  • Serial GC:单线程进行GC,适用于单核或小内存系统。
  • Parallel GC:多线程GC,适用于多核CPU。
  • CMS(Concurrent Mark-Sweep):旨在减少GC停顿时间的回收器,适用于低延迟需求。
  • G1 GC:一个面向大内存和低延迟的垃圾回收器,按区域划分堆内存,优化GC时间。

6. Full GC vs Minor GC

  • Minor GC:发生在年轻代,通常速度较快,但会对性能有轻微影响。
  • Full GC:发生在整个堆(包括年轻代和老年代),通常会暂停应用程序的执行较长时间,因此影响性能较大。

7. GC的停顿时间

  • Stop-the-World:在GC过程中,JVM会暂停应用程序的执行,这被称为"Stop-the-World"事件。垃圾回收器使用不同的算法来减少停顿时间,如G1 GC通过分区域处理减少单次GC停顿时间。

总结

一次完整的GC过程涉及:

  1. 触发条件(如内存不足、显式调用等);
  2. 垃圾回收的不同阶段(如标记、清理、压缩等);
  3. 多种GC算法(如标记-清除、复制算法等);
  4. 多种GC回收器(如Serial、Parallel、CMS、G1等)。

垃圾回收的目标是高效地回收内存,同时尽可能减少对应用程序性能的影响。

相关推荐
NEFU AB-IN4 小时前
Prompt Gen Desktop 管理和迭代你的 Prompt!
java·jvm·prompt
唐古乌梁海10 小时前
【Java】JVM 内存区域划分
java·开发语言·jvm
众俗11 小时前
JVM整理
jvm
echoyu.11 小时前
java源代码、字节码、jvm、jit、aot的关系
java·开发语言·jvm·八股
代码栈上的思考1 天前
JVM中内存管理的策略
java·jvm
thginWalker1 天前
深入浅出 Java 虚拟机之进阶部分
jvm
沐浴露z1 天前
【JVM】详解 线程与协程
java·jvm
thginWalker1 天前
深入浅出 Java 虚拟机之实战部分
jvm
程序员卷卷狗3 天前
JVM 调优实战:从线上问题复盘到精细化内存治理
java·开发语言·jvm
Sincerelyplz3 天前
【JDK新特性】分代ZGC到底做了哪些优化?
java·jvm·后端