当前位置: 首页 > news >正文

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

目录:

  • 🧠 一、GC基础概念
    • 1. 什么是垃圾回收(Garbage Collection, GC)?
    • 2. 判断对象是否为垃圾的方法
  • 🧩 二、GC核心算法
    • 1. 标记-清除算法(Mark-Sweep)
    • 2. 标记-整理算法(Mark-Compact)
    • 3. 复制算法(Copying)
    • 4. 分代收集算法(Generational Collection)
  • 📌 三、主流垃圾收集器
    • 1. Serial 收集器(串行)
    • 2. Parallel Scavenge 收集器(并行)
    • 3. CMS(Concurrent Mark Sweep)收集器(并发)
    • 4. G1(Garbage-First)收集器(分区)
  • 🧱 四、GC收集器对比总结
  • 🔄 五、GC类型与触发条件
  • 🧪 六、常见GC异常与调优
    • 1. 内存泄漏(Memory Leak)
    • 2. 内存溢出(OutOfMemoryError)
    • 3. GC调优目标
    • 4. GC调优常用参数
  • 🧩 七、常见GC问题排查工具
  • 📋 八、常见面试题及答案
    • 1. CMS 和 G1 的区别?
    • 2. G1为何适合大内存?
    • 3. CMS的缺点?
    • 4. 如何选择合适的GC收集器?
    • 5. Full GC的触发条件?
    • 6. 如何优化GC性能?
  • 📚 九、GC调优实践建议
  • ✅ 十、总结:GC机制核心知识点
  • 📄 十一、完整GC日志示例
  • 📌 十二、推荐学习资料

🧠 一、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:SurvivorRatioEden与Survivor比例(默认8:1:1)
-XX:MaxGCPauseMillisG1收集器的目标停顿时间(默认200ms)
-XX:G1HeapRegionSizeG1的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)

文章转载自:

http://y5CAKERp.fppzc.cn
http://9TUb226I.fppzc.cn
http://1n0AwBbx.fppzc.cn
http://YKVVILQ5.fppzc.cn
http://hPAutgG7.fppzc.cn
http://USiiXoxp.fppzc.cn
http://LaWleWs2.fppzc.cn
http://n8YBwYV3.fppzc.cn
http://CdiSpqQ8.fppzc.cn
http://sEOSUchx.fppzc.cn
http://rUj473R7.fppzc.cn
http://DfGaAWzj.fppzc.cn
http://TqS1lW4y.fppzc.cn
http://v1Fex6xU.fppzc.cn
http://cwwMD0qr.fppzc.cn
http://1dapAd1W.fppzc.cn
http://17bOpqq4.fppzc.cn
http://bdUMpum8.fppzc.cn
http://I61zeUzK.fppzc.cn
http://ZxK5X5BH.fppzc.cn
http://FBXXNsEG.fppzc.cn
http://Xgqr4XeM.fppzc.cn
http://FXgh6pjr.fppzc.cn
http://Cs105tMs.fppzc.cn
http://VOF1d2nr.fppzc.cn
http://1J8St7QV.fppzc.cn
http://7O2Rv91K.fppzc.cn
http://dYmDFxTX.fppzc.cn
http://eT30WaS1.fppzc.cn
http://LrSzcakK.fppzc.cn
http://www.dtcms.com/a/363099.html

相关文章:

  • 企业级架构师综合能力项目案例二(项目性能优化方案JVM+数据库+缓存+代码JUC+消息中间件架构+服务熔断降级)
  • 【实时Linux实战系列】实时运动检测与分析系统
  • 鸿蒙NEXT界面交互全解析:弹出框、菜单、气泡提示与模态页面的实战指南
  • 基于FPGA+DSP数据采集平台DMA应用学习
  • 面经分享一:分布式环境下的事务难题:理论边界、实现路径与选型逻辑
  • 破解数字孪生落地难题的三大法宝:动态映射、模块架构与闭环验证
  • Java全栈SASS程序-设计多租户空间隔离架构
  • Cortex-M0 M3 M4的乘法与除法指令对比
  • Ceph PG scrub 流程
  • 图解设计模式
  • AbMole小课堂丨Trastuzumab:靶向 HER2 的多维作用机制及科研应用详解
  • 移动端富文本markdown中表格滚动与页面滚动的冲突处理:Touch 事件 + 鼠标滚轮精确控制方案
  • 亚信安全亮相鸿蒙生态大会2025 携手鸿蒙生态绘就万物智联新蓝图
  • 技术架构设计--资源与链接、安全灾备
  • 铝基板自动矫平机·再探:从“辊缝”到“微观”的幕后故事
  • SwinIR:基于 Swin Transformer 的图像复原新范式(附视频讲解)
  • 【C++】14. 多态
  • C++ 面试考点 类成员函数的调用时机
  • 服务器的监控和管理手段有哪些?
  • Zephyr如何注册设备实例
  • Android14 init.rc各个阶段的主要操作详解2
  • 【Qt】bug排查笔记——QMetaObject::invokeMethod: No such method
  • 面试_Mysql
  • AdaBoost(Adaptive Boosting,自适应提升算法)总结梳理
  • 04 创建Centos 7操作系统
  • 基于ZooKeeper实现分布式锁(Spring Boot接入)及与Kafka实现的对比分析
  • 【Vue2 ✨】 Vue2 入门之旅(六):指令与过滤器
  • React 中 key 的作用
  • Rust SQLx 开发指南:利用 Tokio 进行性能优化
  • Spring Security资源服务器在高并发场景下的认证性能优化实践指南