1、监控工具
命令行: jps、jstat、jmap、jstack、jcmd
jstat:JVM统计监控工具
jmap:堆内存分析工具
jstack:线程堆栈分析工具
图形化: VisualVM、JConsole、JMC (Java Mission Control)
高级工具:
第三方: Arthas、MAT (Memory Analyzer Tool)、YourKit
GCViewer:GC日志分析工具
Arthas:阿里开源的Java诊断工具
Async Profiler:低开销的性能分析工具
生产环境: Prometheus + Grafana + JMX exporter
2、性能与监控
jps:查看Java进程
jstat:监控JVM统计信息(GC、类加载等)
# 每1秒采集一次,共10次
jstat -gcutil <pid> 1000 10
jmap:内存分析
# 查看堆内存配置
jmap -heap <pid>
# 查看对象分布
jmap -histo <pid>
# 观察内存使用和GC情况
jstat -gcutil <pid> 1000
# 使用Native Memory Tracking:
-XX:NativeMemoryTracking=detail
jcmd <pid> VM.native_memory detail
# 生成堆转储文件分析
jmap -dump:live,format=b,file=heap.hprof <pid>
jstack:线程分析
检查线程数、线程状态、锁竞争情况
# 生成线程快照
jstack <pid> > thread.txt
# 调整线程池大小:
-XX:ParallelGCThreads=8
-Djava.util.concurrent.ForkJoinPool.common.parallelism=8
3、参数调优
堆内存设置
# 初始堆大小(建议设为相同值避免动态调整开销)
-Xms4g
# 最大堆大小
-Xmx4g
# 新生代大小(通常为堆的1/3到1/2)
-Xmn2g
# 元空间大小(Java 8+)
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=256
# 调整Survivor区比,Eden:Survivor=8:1:1
-XX:SurvivorRatio=8
# 调整大对象阈值,大于1MB的对象直接进入Old区
-XX:PretenureSizeThreshold=1024*1024
# 根据堆大小调整,通常1-32M
-XX:G1HeapRegionSize=4M
# 优化年轻代大小,当老年代占用35%时触发Mixed GC
-XX:InitiatingHeapOccupancyPercent=35
GC选择:
# 吞吐量优先(Parallel GC)
-XX:+UseParallelGC
-XX:+UseParallelOldGC
# 低延迟优先(CMS或G1)CMS(JDK8及之前)
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
# G1(平衡型 JDK9+默认)
-XX:+UseG1GC
4、GC日志配置
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintHeapAtGC
-XX:+PrintTenuringDistribution
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=5
-XX:GCLogFileSize=20M
-Xloggc:/path/to/gc.log
# Java 9+ 使用统一日志
-Xlog:gc*=info:file=/path/to/gc.log:time,uptime,level,tags
5、高级调优
G1调优参数
# 目标最大停顿时间
-XX:MaxGCPauseMillis=200
# 触发并发标记的堆占用率
-XX:InitiatingHeapOccupancyPercent=45
# 保留内存比例
-XX:G1ReservePercent=10
ZGC调优(JDK11+)
# 启用ZGC
-XX:+UseZGC -Xmx16g
# 并发GC线程数
-XX:ConcGCThreads=4
其它
# 逃逸分析优化
-XX:+DoEscapeAnalysis
# 方法内联控制
-XX:MaxInlineLevel=9
# 代码缓存调优
-XX:ReservedCodeCacheSize=240m
# 偏向锁优化
-XX:+UseBiasedLocking
# 压缩Oops
-XX:+UseCompressedOops
6、常见问题与调优
内存问题: 堆内存使用、非堆内存使用、对象分配速率
OOM错误:分析是堆内存还是非堆内存问题
Full GC频繁: 可能内存泄漏或堆大小设置不合理,老年代空间不足或内存泄漏
解决思路:增加堆大小(-Xmx),调整新生代与老年代比例,检查内存泄漏(分析堆转储)
# 新生代:老年代=1:2
-XX:NewRatio=2
# 限制堆外内存使用:
-XX:MaxDirectMemorySize=512m
GC问题: GC频率、GC耗时、各代内存使用情况
Young GC频繁:Eden区过小或对象分配速率过高,新生代太小、对象过早晋升
解决思路:
增大新生代(-Xmn)
调整晋升阈值(-XX:MaxTenuringThreshold)
增加Survivor区(-XX:SurvivorRatio)
GC停顿时间过长:
选择合适的GC算法,切换到低延迟收集器(G1或ZGC)
# 使用G1收集器,目标最大停顿200ms
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
# 使用CMS收集器(针对大数据处理场景)
-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
CPU问题: CPU使用率、热点方法
CPU使用率高:查找热点方法或线程死循环
上下文切换频繁:线程数设置不合理