Java 垃圾回收机制(GC算法、GC收集器如G1、CMS)的必会知识点汇总

发布于:2025-09-03 ⋅ 阅读:(12) ⋅ 点赞:(0)

🧠 一、GC基础概念

1. 什么是垃圾回收(Garbage Collection, GC)?

  • 作用:自动管理内存,回收不再使用的对象,防止内存泄漏和溢出。
  • 核心问题
    (1) 如何判断对象是垃圾?
    (2)如何高效回收垃圾?

2. 判断对象是否为垃圾的方法

方法 说明
引用计数法 每个对象维护一个引用计数器,引用增加时计数+1,引用失效时-1。无法解决循环引用问题。
可达性分析法 从GC Roots出发,不可达的对象判定为垃圾。GC Roots包括:虚拟机栈中的局部变量、类静态属性引用、常量引用、JNI引用。

🧩 二、GC核心算法

1. 标记-清除算法(Mark-Sweep)

  • 步骤
    (1)标记:从GC Roots出发,标记所有存活对象。
    (2)清除:回收未被标记的对象。
  • 缺点
    (1)产生内存碎片(可能导致大对象分配失败)。
    (2)标记和清除效率较低。

2. 标记-整理算法(Mark-Compact)

  • 步骤
    (1)标记:同标记-清除。
    (2)整理:将存活对象向一端移动,清理边界外内存。
  • 优点:避免内存碎片。
  • 缺点:移动对象需要暂停所有线程(Stop-The-World)。

3. 复制算法(Copying)

  • 步骤
    (1)将内存分为两块,每次只用一块。
    (2)回收时,将存活对象复制到另一块,清空原区域。
  • 优点:高效,无内存碎片。
  • 缺点:内存利用率低(只使用一半)。

4. 分代收集算法(Generational Collection)

  • 思想:将堆内存划分为新生代(Young Generation)和老年代(Old Generation)。
  • 新生代:对象生命周期短,使用复制算法。
  • 老年代:对象生命周期长,使用标记-清除或标记-整理。

📌 三、主流垃圾收集器

1. Serial 收集器(串行)

  • 特点:单线程,适用于单核CPU或小内存场景。
  • 使用场景:Client模式(如桌面应用)。
  • 命令行参数
    -XX:+UseSerialGC

2. Parallel Scavenge 收集器(并行)

  • 特点:多线程,关注吞吐量(吞吐优先)。
  • 使用场景:后台计算任务(如批量处理)。
  • 命令行参数
    -XX:+UseParallelGC

3. CMS(Concurrent Mark Sweep)收集器(并发)

  • 目标:以最短停顿时间为目标,适合高并发、低延迟的Web应用。
  • 回收步骤:
    (1)初始标记(Initial Mark):暂停所有线程,标记GC Roots直接关联的对象。
    (2)并发标记(Concurrent Mark):并发标记所有存活对象。
    (3)重新标记(Remark):暂停线程,处理并发标记期间新增的对象。
    (4)并发清除(Concurrent Sweep):并发清除垃圾对象。
  • 优点:低停顿时间。
  • 缺点
    (1)内存碎片化(可能导致Full GC)。
    (2)对CPU资源敏感。
  • 命令行参数
    -XX:+UseConcMarkSweepGC

4. G1(Garbage-First)收集器(分区)

  • 目标:兼顾吞吐量和低延迟,适用于大内存(>6GB)和多核CPU。
  • 核心思想
    (1) 将堆内存划分为多个Region(大小相等,1~32MB)。
    (2) 优先回收垃圾最多的Region。
  • 回收步骤
    (1)初始标记(Initial Mark):暂停线程,标记GC Roots。
    (2)并发标记(Concurrent Mark):并发标记存活对象。
    (3)最终标记(Final Mark):处理并发标记期间新增的对象。
    (4)筛选回收(Live Data Counting and Evacuation):选择回收价值高的Region进行回收。
  • 优点
    可预测的停顿时间(通过 -XX:MaxGCPauseMillis 设置)。
    避免内存碎片(回收时进行压缩)。
  • 缺点
    内存占用较高(维护Region状态)。
  • 命令行参数
    -XX:+UseG1GC

🧱 四、GC收集器对比总结

在这里插入图片描述

🔄 五、GC类型与触发条件

在这里插入图片描述

🧪 六、常见GC异常与调优

1. 内存泄漏(Memory Leak)

  • 原因:对象不再使用但无法被GC回收(如缓存未清理、监听器未注销)。
  • 定位工具
    (1) MAT(Memory Analyzer):分析堆转储(heap dump)。
    (1) VisualVM:实时监控内存使用情况。
    (3) jmap + jhat:生成并分析堆转储。

2. 内存溢出(OutOfMemoryError)

  • 常见类型
    • Java heap space:堆内存不足。
    • GC overhead limit exceeded:GC频繁且效率低。
    • PermGen / Metaspace:方法区或元空间内存不足。
  • 解决方法
    • 增加堆大小(-Xmx)。
    • 调整元空间大小(-XX:MaxMetaspaceSize)。
    • 优化代码(减少对象创建、及时释放资源)。

3. GC调优目标

目标 说明
吞吐量(Throughput) 单位时间内处理任务的效率(适合后台计算任务)
停顿时间(Pause Time) 每次GC暂停的时间(适合Web服务)
内存占用(Footprint) 堆内存使用量(适合内存敏感场景)

4. GC调优常用参数

参数 说明
-Xms / -Xmx 设置堆初始和最大大小(如 -Xms2g -Xmx4g)
-XX:NewRatio 新生代与老年代比例(默认1:2)
-XX:SurvivorRatio Eden与Survivor比例(默认8:1:1)
-XX:MaxGCPauseMillis G1收集器的目标停顿时间(默认200ms)
-XX:G1HeapRegionSize G1的Region大小(1~32MB)
-XX:+PrintGCDetails 打印详细GC日志
-XX:+PrintGCDateStamps 打印GC时间戳
-Xloggc:/path/to/gc.log 输出GC日志到文件

🧩 七、常见GC问题排查工具

工具 说明
jstat 实时监控GC状态(如 jstat -gc 1234 1000 每秒输出GC信息)
jmap 生成堆转储(jmap -dump:format=b,file=heap.bin 1234)
jhat 分析堆转储(jhat heap.bin)
VisualVM 图形化监控JVM内存、线程、GC等
MAT(Memory Analyzer) 分析堆转储,定位内存泄漏
GC 日志分析工具 如 GCViewer、GCEasy、GCPlot

📋 八、常见面试题及答案

1. CMS 和 G1 的区别?

在这里插入图片描述

2. G1为何适合大内存?

  • 分区管理:将堆划分为多个Region,可并行回收。
  • 可预测停顿:通过 -XX:MaxGCPauseMillis 设置目标停顿时间。
  • 避免碎片化:回收时进行压缩(Evacuation阶段)。

3. CMS的缺点?

  • 内存碎片化:可能导致Full GC(标记-清除算法的缺点)。
  • 并发阶段耗CPU:并发标记和清除阶段占用CPU资源。
  • Concurrent Mode Failure:老年代空间不足导致并发失败,退化为Serial Old收集器。

4. 如何选择合适的GC收集器?

在这里插入图片描述

5. Full GC的触发条件?

  • 老年代空间不足。
  • 方法区(元空间)内存不足。
  • 调用 System.gc()(可禁用 -XX:+DisableExplicitGC)。
  • 分配大对象(如大数组)。

6. 如何优化GC性能?

  • 合理设置堆大小:避免频繁GC。
  • 避免内存泄漏:使用缓存时注意释放。
  • 选择合适收集器:如G1适合大内存。
  • 监控GC日志:分析停顿时间和频率。

📚 九、GC调优实践建议

在这里插入图片描述

✅ 十、总结:GC机制核心知识点

在这里插入图片描述

📄 十一、完整GC日志示例

2023-10-23T15:30:00.123+0800: [GC (Allocation Failure) [PSYoungGen: 131072K->15360K(157248K)] 131072K->15360K(503936K), 0.0123456 secs] [Times: user=0.05 sys=0.00, real=0.01 secs]

日志解析

  • GC类型:Allocation Failure(分配失败触发GC)。
  • GC区域:PSYoungGen(Parallel Scavenge新生代)。
  • 内存变化:131072K->15360K(回收后内存占用)。
  • 耗时:0.0123456 secs(GC耗时)。

📌 十二、推荐学习资料

  • 《深入理解 Java 虚拟机》(周志明)
  • 《Java 性能调优指南》
  • JVM 官方文档:https://docs.oracle.com/en/java/javase/17/gctuning/
  • GC日志分析工具:GCViewer、GCEasy、GCPlot
  • JVM调优视频教程(B站、慕课网、CSDN)