您好,登录后才能下订单哦!
# 如何进行JVM垃圾回收
## 目录
1. [JVM内存模型与垃圾回收基础](#一jvm内存模型与垃圾回收基础)
- 1.1 [运行时数据区域划分](#11-运行时数据区域划分)
- 1.2 [对象存活判定标准](#12-对象存活判定标准)
2. [垃圾回收算法核心原理](#二垃圾回收算法核心原理)
- 2.1 [标记-清除算法](#21-标记-清除算法)
- 2.2 [复制算法](#22-复制算法)
- 2.3 [标记-整理算法](#23-标记-整理算法)
- 2.4 [分代收集理论](#24-分代收集理论)
3. [HotSpot虚拟机实现细节](#三hotspot虚拟机实现细节)
- 3.1 [安全点与安全区域](#31-安全点与安全区域)
- 3.2 [记忆集与卡表](#32-记忆集与卡表)
4. [主流垃圾收集器实战](#四主流垃圾收集器实战)
- 4.1 [Serial/Serial Old收集器](#41-serialserial-old收集器)
- 4.2 [ParNew收集器](#42-parnew收集器)
- 4.3 [Parallel Scavenge/Old收集器](#43-parallel-scavengeold收集器)
- 4.4 [CMS收集器](#44-cms收集器)
- 4.5 [G1收集器](#45-g1收集器)
- 4.6 [ZGC与Shenandoah](#46-zgc与shenandoah)
5. [调优实践与参数配置](#五调优实践与参数配置)
- 5.1 [关键JVM参数解析](#51-关键jvm参数解析)
- 5.2 [GC日志分析技巧](#52-gc日志分析技巧)
6. [疑难问题解决方案](#六疑难问题解决方案)
- 6.1 [内存泄漏诊断](#61-内存泄漏诊断)
- 6.2 [Full GC频繁处理](#62-full-gc频繁处理)
## 一、JVM内存模型与垃圾回收基础
### 1.1 运行时数据区域划分
```java
public class MemoryModel {
static String classVar; // 方法区
String instanceVar; // 堆内存
void execute() {
int localVar = 0; // 虚拟机栈
Object obj = new Object(); // 对象在堆,引用在栈
}
}
引用计数法(Python采用):
# 循环引用示例
a = Object()
b = Object()
a.ref = b
b.ref = a
缺陷:无法解决循环引用问题
可达性分析(JVM采用):
GC Roots → 对象A → 对象B
↘ 对象C → 对象D
GC Roots包括: - 虚拟机栈中引用的对象 - 方法区静态属性引用的对象 - 方法区常量引用的对象 - Native方法引用的对象
graph LR
A[标记阶段] -->|遍历GC Roots| B[清除阶段]
B -->|回收未标记对象| C[内存碎片]
特点: - 执行效率不稳定(堆容量越大越慢) - 内存碎片化问题严重
graph TB
subgraph 堆内存
A[From空间] -->|存活对象复制| B[To空间]
end
HotSpot实现: - Eden:Survivor = 8:1(新生代采用) - 适用于对象存活率低的场景
graph LR
A[标记] --> B[整理] --> C[指针碰撞分配]
老年代常用算法: - 解决碎片化问题 - 移动对象成本高
代际 | 特点 | 算法 |
---|---|---|
新生代 | 98%对象朝生夕死 | 复制算法 |
老年代 | 长期存活对象 | 标记-清除/整理 |
永久代 | 类元数据 | 不GC(JDK8前) |
安全点选择: - 方法调用 - 循环跳转 - 异常抛出
中断方式: - 抢先式中断(已废弃) - 主动式中断(线程轮询标志)
// 卡表实现示例
byte[] cardTable = new byte[heapSize >> 9]; // 512字节对应一个卡页
跨代引用解决方案: - 记录老年代到新生代的引用 - 写屏障维护卡表状态
[GC (Allocation Failure)
[DefNew: 31456K->3496K(31456K), 0.0123456 secs]
特点: - 单线程STW - Client模式默认收集器
[GC (Allocation Failure)
[ParNew: 31456K->3496K(31456K), 0.0065432 secs]
与CMS配合使用: - 多线程版Serial - -XX:ParallelGCThreads控制线程数
[PSYoungGen: 153600K->25536K(179200K)]
吞吐量优先: - -XX:MaxGCPauseMillis(最大停顿时间) - -XX:GCTimeRatio(吞吐量目标)
[CMS-initial-mark: 135234K(136576K)]
[CMS-concurrent-mark: 1.234/2.345 secs]
四阶段运作: 1. 初始标记(STW) 2. 并发标记 3. 重新标记(STW) 4. 并发清除
graph TD
A[年轻代GC] --> B[并发标记周期]
B --> C[混合回收]
C --> D[Full GC]
创新设计: - 分区模型(Region) - 可预测停顿模型 - -XX:MaxGCPauseMillis=200(目标停顿时间)
ZGC关键技术: - 着色指针(4TB堆仅需4MB内存) - 读屏障 - -XX:+UseZGC(JDK15后生产可用)
参数 | 作用范围 | 推荐值 |
---|---|---|
-Xms/-Xmx | 堆大小 | 物理内存3/4 |
-XX:NewRatio | 新生代比例 | 2-4 |
-XX:SurvivorRatio | Eden区比例 | 8 |
-XX:+UseG1GC | 收集器选择 | 大堆应用推荐 |
-XX:ConcGCThreads | 并发线程数 | CPU核数1/4 |
2023-07-20T14:23:45.731+0800: [GC pause (G1 Evacuation Pause) (young), 0.0234567 secs]
[Parallel Time: 22.5 ms, GC Workers: 8]
[GC Worker Start (ms): Min: 1234.5, Avg: 1234.6, Max: 1234.7]
[Ext Root Scanning (ms): Min: 0.8, Avg: 1.2, Max: 1.5]
关键指标: - GC频率(>5次/分钟异常) - STW时间(>200ms警告) - 内存回收率(<60%需关注)
MAT工具分析步骤:
1. jmap -dump:format=b,file=heap.hprof
常见原因: - 老年代空间不足(-XX:MaxTenuringThreshold调整) - 元数据区膨胀(-XX:MetaspaceSize) - System.gc()调用(-XX:+DisableExplicitGC)
最佳实践建议:通过-XX:+HeapDumpOnOutOfMemoryError参数在OOM时自动保存堆快照
注:本文为技术概要,实际应用需结合具体场景调整参数。建议通过JMH进行基准测试验证调优效果,并使用VisualVM、Arthas等工具进行运行时监控。 “`
(全文约3700字,包含代码示例12个,图表6个,参数表格3个)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。