基本参数
java -version/-help
-XX参数
调优使用,例如设置堆内存大小
-XX:MaxHeapSize=100M
#参数简写方式
-Xms100M = -XX:InitialHeapSize=100M
添加JVM参数-XX:+PrintFlagsFinal

#查看当前Java进程
jps
#查看当前JVM参数
jinfo -falgs PID
#查看老年代、新生代的比例 默认是2:1
jinfo -flag NewRatio 12228
-XX:NewRatio=2
#查看Eden和S区的比例 默认8:1:1
jinfo -flag SurvivorRatio 12228
-XX:SurvivorRatio=8
#查看装载的类数量 可以打印GC详情信息 -verbose:gc -XX:+PrintGCDetails
jstat -class 12228
Loaded Bytes Unloaded Bytes Time
16331 30183.4 0 0.0 21.23
#查看当前进程GC分布的情况
jstat -gc 10076
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
32768.0 24064.0 0.0 24041.6 406528.0 100342.3 195584.0 47452.5 83504.0 77530.6 11568.0 10542.4 13 0.530 3 0.474 1.004
#查看此时的堆栈线程 如果有死锁也会出现最后日志
jstack PID
#查看当前堆内存的详细情况
jmap -heap 10076
Attaching to process ID 10076, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.151-b12
using thread-local object allocation.
Parallel GC with 4 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 4206886912 (4012.0MB)
NewSize = 88080384 (84.0MB)
MaxNewSize = 1401946112 (1337.0MB)
OldSize = 176160768 (168.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
PS Young Generation
#可以看到Eden区和S区并没有达到8:1:1,因为JVM会根据当前的业务代码的对象大小动态去调整Eden、s0、s1的大小
Eden Space:
capacity = 416284672 (397.0MB)
used = 105738816 (100.84039306640625MB)
free = 310545856 (296.15960693359375MB)
25.40060278750787% used
From Space:
capacity = 24641536 (23.5MB)
used = 24618584 (23.478111267089844MB)
free = 22952 (0.02188873291015625MB)
99.90685645570146% used
To Space:
capacity = 33554432 (32.0MB)
used = 0 (0.0MB)
free = 33554432 (32.0MB)
0.0% used
PS Old Generation
capacity = 200278016 (191.0MB)
used = 48591400 (46.340370178222656MB)
free = 151686616 (144.65962982177734MB)
24.26197391529982% used
也可以直接在Java中获取ManagementFactory.getMemoryPoolMXBeans()获取到上述的使用情况
| 参数 | 含义 | 说明 |
|---|---|---|
| -XX: CICompilerCount | 最大并行编译数 | 如果设置大于1,虽然编译速度会提高,但是影响系统稳定性,会增加JVM崩溃的可能 |
| -XX:InitialHeapSize=100M | 初始堆大小 | 简写-Xms 100M |
| -XX:MaxHeapSize=100M | 最大堆大小 | 简写-Xmx 100M |
| -XX:NewSize=20M | 设置年轻代的大小 | 官网建议不要轻易去修改年轻代大小 |
| -XX:MaxNewSize=20M | 设置年轻代最大的大小 | 官网建议不要轻易去修改年轻代大小 |
| -XX:OldSize=20M | 设置老年代的大小 | |
| -XX:MetaspaceSize=20M | 设置方法区的大小 | |
| -XX:MaxMetaspaceSize=20M | 设置最大方法区的大小 | |
| -XX:UseParallelGC | 使用ParallelGC | 新生代、吞吐量优先 |
| -XX:UseParallelOldGC | 使用ParallelOldGC | 老年代、吞吐量优先 |
| -XX:UseConcMarkSweepGC | 使用CMS | 老年代、停顿时间优先 |
| -XX:UseG1GC | 使用G1GC | 新老年代、停顿时间优先 |
| -XX:NewRatio | 新老生代的比值 | 例如–XX:NewRatio=3,则老年代:新生代=3:1 |
| -XX:SurvivorRatio | S区和Eden区的比值 | 默认-XX:SurvivorRatio=8,Eden和两个S区是8:1:1 |
| -XX:HeapDumpOnOutOfMemoryError | 启动堆内存溢出打印 | 当JVM堆内存溢出时,也就是OOM,自动生成dump文件 |
| -XX:HeapDumpPath | 指定堆内存溢出的打印路径 | 在指定目录生成一个heap.hprof文件 |
| -XX:PrintGCDetails -XX:PrintGCTimeStamps -XX:PrintGCDateStamps -Xloggc:gc.log | 打印GC日志 | 对比不同的垃圾收集器查看 |
| -Xss128k | 设置每个线程的堆栈大小 | |
| -XX:MaxTenuringThreshold=6 | 设置老年代的最大临界值 | 分代年龄默认15 |
| -XX:InitiatingHeapOccupancyPercent | 启动并发GC周期的内存使用占比 | 默认45%,0一直执行GC循环 |
| -XX:G1HeapWastePercent | 运行浪费空间的占比 | 默认10%,如果标记可回收的空间小于10%则立即出发MixedGC |
| -XX:MaxGCPauseMillis=300ms | G1最大停顿时间 | 暂停时间不能太小,否则会导致GC跟不上垃圾产生的速度,最终Full GC |
#保存堆内存信息
jmap -dump:file=heap.hprot 10076
#查看堆内存信息 会启动一个7000端口 直接在浏览器中查看
jhat heap.hprot
上面是即时的,现在需要是发生OOM的时候保存
#当服务发生OOM时保存堆内存快照文件 可以用工具查看详情
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof
jconsole 查看java进程的信息

jvisualvm 比jconsole显示更全面,在工具-插件中安装Visual GC,上篇文章有详细使用,本文不做介绍
jmc 和上述差不多
#通过添加JVM参数 将GC日志打印出来,使用的是默认的收集器Parallel
-XX:MaxHeapSize=100M -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:gc.log
日志内容分析
#启动young GC,原因分配对象失败 堆内存总共29696K已使用22897K 触发回收后4086K 98304K总共内存
2022-07-04T16:58:44.281+0800: 0.714: [GC (Allocation Failure) [PSYoungGen: 22897K->4086K(29696K)] 22897K->15737K(98304K), 0.0290035 secs] [Times: user=0.03 sys=0.02, real=0.03 secs]
分析日志工具
三个调优角度:堆
InitiatingHeapOccupancyPercent)InitiatingHeapOccupancyPercentG1HeapWastePercentG1MixedGCLiveThresholdPercentConcGCThreads=nOOM可以通过新老年代的比例来完成调优
其他的常见方式
选择合适的垃圾收集器,两个维度吞吐量和停顿时间
频繁的GC怎么办?
YoungGC:是否是young区空间不够了,如果是够的是否是Eden区和s区比例分配不均匀
Old GC 空间不够,老年代界限值太低,metaspace空间是否不够(栈帧深度(递归))
流程,表,时序图。难点和需要注意的点
以上就是本章的全部内容了。
上一篇:JVM第二话 – JVM内存模型以及垃圾回收
下一篇:SpringCloud第一话 – Eureka服务注册中心
书山有路勤为径,学海无涯苦作舟