文章目录
-
- 一、JVM调优概述
- 二、JVM调优目标
- 三、JVM定位瓶颈
- 四、JVM内存调优
-
- [1. 调整堆内存大小](#1. 调整堆内存大小)
- 2.调整新生代与老年代比例
- 3.元空间(Metaspace)调优
- 五、垃圾回收(GC)调优
-
-
- [**1. 选择合适的 GC 算法**](#1. 选择合适的 GC 算法)
- [**2. 优化 GC 参数**](#2. 优化 GC 参数)
- [3.启用 GC 日志](#3.启用 GC 日志)
-
- 六、线程与锁优化
- 七、调优后的验证
- 八、注意事项
一、JVM调优概述
JVM 调优是优化 Java 应用程序性能的关键环节,目的是通过调整 JVM 参数、优化垃圾回收(GC)策略、减少内存泄漏和资源竞争等问题,提升程序的吞吐量、降低延迟,并确保系统在高负载下的稳定性。
二、JVM调优目标
- 提高吞吐量(Throughput)
- 降低延迟(Latency)
- 减少内存占用
- 避免Full GC导致的停顿
三、JVM定位瓶颈
内存泄漏:老年代(Old Gen)持续增长,频繁Full GC。
GC问题:Young GC频繁或Full GC停顿过长。
线程问题:死锁、线程阻塞或上下文切换频繁。
四、JVM内存调优
1. 调整堆内存大小
-
参数:
-Xms
(初始堆大小)、-Xmx
(最大堆大小) -
原则:
-Xms
和-Xmx
设为相同值,避免堆动态扩容的开销。- 根据应用需求设置,避免过大(导致 GC 停顿长)或过小(导致频繁 GC)。
-
示例:
shelljava -Xms4g -Xmx4g -jar app.jar
2.调整新生代与老年代比例
- 参数:
-XX:NewRatio
(新生代与老年代的比例)- 默认值:
-XX:NewRatio=2
(老年代是新生代的 2 倍)。 - 对于短生命周期对象多的应用,增大新生代比例(如
-XX:NewRatio=1
)。
- 默认值:
- 参数:
-XX:SurvivorRatio
(Eden 区与 Survivor 区的比例)- 默认值:
-XX:SurvivorRatio=8
(Eden:S0:S1 = 8:1:1)。 - 增大 Eden 区可减少对象晋升到老年代的频率。
- 默认值:
3.元空间(Metaspace)调优
-
参数:
-XX:MetaspaceSize
、-XX:MaxMetaspaceSize
-
避免元空间动态扩容导致的 Full GC。
shell-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m
五、垃圾回收(GC)调优
1. 选择合适的 GC 算法
- 串行 GC(Serial GC)
- 参数:
-XX:+UseSerialGC
- 适用场景:单核、低延迟不敏感的小型应用(如客户端程序)。
- 参数:
- 并行 GC(Parallel GC)
- 参数:
-XX:+UseParallelGC
- 适用场景:多核 CPU、高吞吐量优先(如数据处理应用)。
- 参数:
- CMS GC(Concurrent Mark Sweep)
- 参数:
-XX:+UseConcMarkSweepGC
- 适用场景:低延迟需求,但可能产生内存碎片。
- 参数:
- G1 GC(Garbage-First)
- 参数:
-XX:+UseG1GC
- 适用场景:大堆内存(>4GB)、平衡吞吐量和延迟(默认 JDK 9+)。
- 参数:
- ZGC / Shenandoah
- 参数:
-XX:+UseZGC
(JDK 15+)或-XX:+UseShenandoahGC
- 适用场景:超低延迟(停顿时间 < 10ms)、超大堆内存(TB 级)。
- 参数:
2. 优化 GC 参数
- 控制 Young GC 频率:
- 避免晋升失败(Promotion Failure):
- 增大 Survivor 区或调整
-XX:TargetSurvivorRatio
(默认 50%)。
- 增大 Survivor 区或调整
3.启用 GC 日志
-
参数:
shell-Xloggc:/path/to/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10M
六、线程与锁优化
- 减少锁竞争
- 使用无锁数据结构(如
ConcurrentHashMap
)。 - 缩短锁的持有时间(如缩小同步代码块)。
- 使用无锁数据结构(如
- 线程池调优
- 合理设置线程池大小(CPU 密集型 vs IO 密集型)。
- 避免无界队列(如
newFixedThreadPool
默认使用无界队列)。
- 生成线程快照(Thread Dump)
- 使用
jstack <pid>
或Arthas
分析死锁和线程阻塞。
- 使用
七、调优后的验证
- 压力测试
- 使用工具(如 JMeter、Gatling)模拟高并发场景。
- 持续监控
- 使用 APM 工具(如 SkyWalking、Prometheus + Grafana)监控调优效果。
八、注意事项
- 避免过度调优:优先优化代码逻辑(如算法、SQL),再调整 JVM 参数。
- 逐步调整:每次只修改一个参数,观察效果后再继续。
- 生产环境谨慎 :某些参数(如
-XX:+AggressiveOpts
)可能导致不稳定。
通过结合监控工具、合理调整参数,并持续验证效果,JVM 调优可以显著提升 Java 应用的性能和稳定性。