概述
JDK17 作为当前主流的 LTS(长期支持)版本,其 GC(垃圾回收)性能对 Java 应用的执行效率至关重要。本文将系统梳理 JDK17 中 GC 调优的核心策略,包括 JVM 参数分类、内存布局优化、GC 算法选择及参数定制、GC 日志处理等关键内容,帮助开发者掌握 GC 调优的核心技能。
一、JVM 参数分类
JDK17 中 JVM 参数分为三类:
1. 标准参数(以开头)
- 所有 HotSpot 都支持
- 常用示例:
version,verbose:class,verbose:gc - 通过
java -?或java -help查看全部
2. 非标准参数(以X开头)
- 特定 HotSpot 版本支持
- 常用示例:
Xms200M: 设置初始堆内存Xmx200M: 设置最大堆内存Xint: 解释执行Xcomp: 编译执行Xbatch: 禁用后台编译
3. 不稳定参数(以XX开头)
- 与特定 HotSpot 版本对应
- 常用示例:
XX:+PrintFlagsFinal: 打印最终生效的参数XX:MaxHeapSize: 设置最大堆内存XX:MetaspaceSize: 设置元空间大小
💡 提示:JDK17 默认使用的垃圾回收器是 G1。
二、GC 调优三部曲(从 RocketMQ 学习)
RocketMQ 的 GC 调优策略可归纳为三个核心步骤:
1. 调整内存布局
- 设置堆内存大小(
Xms,Xmx) - 设置元空间大小(
XX:MetaspaceSize,XX:MaxMetaspaceSize) - 设置线程栈空间(
Xss) - 设置热点代码缓存空间
- 应用程序类数据共享(AppCDS)
2. 选择 GC 算法并定制参数
- JDK17 中主要使用 G1 或 ZGC
- 根据应用特性选择合适的 GC 算法
3. 打印 GC 日志
- 便于分析 GC 性能
- 使用
Xlog统一参数打印 GC 日志
三、基于 JDK17 优化 JVM 内存布局
1. 定制堆内存大小
| 参数 | 说明 | 常见配置 |
|---|---|---|
-Xms | 设置堆内存初始大小 | -Xms4g |
-Xmx | 设置堆内存最大大小 | -Xmx4g |
-XX:MinHeapFreeRatio | GC 后堆空间最小比例 | -XX:MinHeapFreeRatio=20 |
-XX:MaxHeapFreeRatio | GC 后堆空间最大比例 | -XX:MaxHeapFreeRatio=70 |
💡 建议:生产环境通常将-Xms 和-Xmx 设置为相同值,减少运行时内存申请。
2. 定制非堆内存大小
2.1 元空间(Metaspace)
- JDK8 后取代永久代(PermGen)
- 直接使用本地内存,受操作系统限制
- 关键参数:
XX:MetaspaceSize: 元空间初始大小(触发 GC 的阈值)XX:MaxMetaspaceSize: 元空间最大值
2.2 线程栈空间
Xss: 设置线程栈空间大小(默认 1024KB)XX:ThreadStackSize: 与Xss作用类似
2.3 热点代码缓存空间
- 用于存储编译后的热点代码
- 关键参数:
XX:InitialCodeCacheSize: 代码缓存初始大小XX:ReservedCodeCacheSize: 代码缓存最大大小XX:+SegmentedCodeCache: 启用代码缓存分割(JDK17 默认启用)
3. 应用程序类数据共享(AppCDS)
- 将类信息归档到文件,后续 JVM 进程可重用
- 用法示例:
# 将类信息归档到hello.jsa文件java -Xshare:dump -XX:SharedArchiveFile=hello.jsa -version# 使用归档文件启动java -XX:SharedArchiveFile=hello.jsa -Xlog:class+load -version
四、基于 JDK17 定制 JVM 的 GC 参数
1. G1 重要参数
| 参数 | 说明 | RocketMQ 配置 | 默认值 |
|---|---|---|---|
-XX:+UseG1GC | 启用 G1 垃圾回收器 | 启用 | JDK17 默认启用 |
-XX:G1HeapRegionSize | 设置 Region 大小 | 16m | 堆大小/2048 |
-XX:G1ReservePercent | 保留堆空间比例 | 25% | 10% |
-XX:InitiatingHeapOccupancyPercent | 并发标记触发阈值 | 30% | 45% |
-XX:SoftRefLRUPolicyMSPerMB | 软引用过期时间 | 0 | 1000ms |
💡 关键点:G1 不再有固定年轻代,不要设置-Xmn 参数。
2. ZGC 重要参数
| 参数 | 说明 | 说明 |
|---|---|---|
-XX:+UseZGC | 启用 ZGC | 低延迟垃圾回收器,停顿时间 <10ms |
-XX:ZAllocationSpikeTolerance | 分配波动容忍度 | 默认 2.0 |
-XX:ZCollectionInterval | GC 周期间隔 | 默认 0(禁用) |
-XX:ZFragmentationLimit | 堆碎片限制 | 默认 25% |
-XX:+ZProactive | 启用主动 GC 周期 | 默认启用 |
-XX:+ZUncommit | 启用未使用堆内存释放 | 默认启用 |
💡 关键点:ZGC 适合 TB 级大堆内存场景,通常只需指定-Xmx 即可。
五、GC 日志处理
JDK8 后,GC 日志统一使用-Xlog参数:
-Xlog:gc*:file=${GC_LOG_DIR}/gc.log:time,tags:filecount=5,filesize=30Mgc*: 打印每次 GC 的详细信息file: 文件名time,tags: 日志格式filecount=5,filesize=30M: 保留 5 个文件,每个文件 30MB
💡 最佳实践:使用 gceasy 等工具分析 GC 日志,优化 GC 性能。
六、其他 JVM 调优小经验
1. 远程断点调试
- 用于在远程服务器上调试 Java 应用
- 配置示例:
java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005-jar yourapp.jar - 在 IDEA 中配置远程调试环境
2. JVM 调优学习建议
- 重框架:注重整体逻辑自洽,不纠结细节
- 形成习惯:在日常工作中不断积累 JVM 知识
- 重表达:能清晰表达 JVM 知识,提升沟通效率
七、章节总结
GC 调优是 Java 程序员的必备技能。JDK17 中,G1 和 ZGC 是主要的垃圾回收器。调优 GC 需要:
- 了解 JVM 内存布局:堆内存、非堆内存
- 选择合适的 GC 算法:G1 适合 6GB 以上堆内存,ZGC 适合 TB 级大堆
- 定制 GC 参数:根据应用特性调整关键参数
- 分析 GC 日志:使用工具辅助优化
💡 关键结论:GC 调优没有标准答案,需要在实际项目中不断尝试和优化。