一、常用JVM参数
1.1 标准参数
-version -help -server -cp
1.2 -X参数
非标准参数,不同JDK版本可能不同
设置采用解释器/JIT编译器
- -Xint:采用解释器执行
- -Xcomp:采用即时编译器执行(如果即时编译器出现问题,解释器会介入)
- -Xmixed:采用解释器和JIT编译器混合使用(默认模式)
1.3 -XX参数
使用最多的参数,非标准化参数。主要用于JVM调优和debug
- Boolean类型
格式:-XX:[+/-]<name> 表示启用或禁用name属性(+表示启用,-表示禁用) 如:-XX:+UseG1GC 表示启用G1垃圾收集器
- 非Boolean类型
格式:-XX:<name>=<value> 表示name属性的值为value 如:-XX:MaxHeapSize=100M 表示最大堆空间为100M
1.4 其它参数
-Xms1000: 初始堆内存大小,等价于-XX:InitialHeapSize=1000 -Xmx1000:最大堆内存大小,等价于-XX:MaxHeapSize=1000 -Xss100:每个线程虚拟机栈和堆栈的大小,等价于-XX:ThreadStackSize=100
1.5 查看所有参数
java -XX:+PrintFlagsFinal -version
= 后面的值为默认值
:= 后面的值被修改后的值
1.6 设置参数的方式
- 开发工具中设置,如idea、eclipse
- 运行jar包时:java -XX:MaxHeapSize=100M xxx.jar
- web容器,如tomcat,可在运行脚本中设置
- 通过jinfo实时修改某个进程的参数。(只能修改被manageable标记的参数)
1.7 常用参数
参数 | 含义 | 备注 |
-XX:CICompiler=3 | 最大并行编译数 | 如果设置大于1,虽然编译速度会提高,但同样影响系统稳定性,会增加JVM奔溃的可能 |
-XX:InitialHeapSize=100M | 初始堆内存大小 | 简写-Xms100M |
-XX:MaxHeapSize=100M | 最大堆大小 | 简写-Xmx100M |
-XX:NewSize=20M | 新生代大小 | |
-XX:MaxNewSize=50M | 新生代最大大小 | |
-XX:OldSize=50M | 老年代大小 | |
-XX:MetaspaceSize=50M | 方法区大小 | |
-XX:MaxMetaspaceSize=50M | 方法区最大大小 | |
-XX:+/-UseParallelGC | 是否使用ParallelGC | 新生代垃圾收集器,吞吐量优先 |
-XX:+/-UseParallelOldGC | 是否使用ParallelOldGC | 老年代代垃圾收集器,吞吐量优先 |
-XX:+/-UseConcMarkSweepGC | 是否使用CMS | 老年代垃圾收集器,停顿时间优先 |
-XX:+/-UseG1GC | 是否使用G1GC | 新生代/老年代代垃圾收集器,吞吐量优先 |
-XX:NewRation | 新生代和老年代的比值 | 如-XX:NewRatio=4,表示新生代:老年代=1:4 |
-XX:SurvivorRatio | Survivor区和Eden区的比值 | 如-XX:SurvivorRatio=8,表示Survivor区:Eden区=1:8 |
-XX:+/-HeapDumpOnOutOfMemoryError | 是否开启堆内存溢出时打印 | 当堆OOM时,会自动生成dump文件 |
-XX:HeapDumpPath=heap.hprof | 指定堆内存溢出时打印目录 | 表示在当前目录生成一个heap.hprof |
-XX:+/-PrintGCDetails | 打印GC日志 | 可以使用不同的垃圾收集器,对比查看GC情况 |
-Xss128k | 设置每个线程的堆栈大小 | |
-XX:MaxTenuringThreshold=6 | 对象进入老年代的年龄阈值 | 默认值为15 |
-XX:InitiatingHeapOccupancyPercent | 当整个堆占用超过某个百分比时,就会触发并发GC周期 | 基于整个堆的占用率,默认值为45 |
-XX:G1HeapWastePercent | 允许整个堆内存中被浪费的空间的百分比 | 默认值为5%。如果并发标记可回收的空间小于5%,则不会触发MixedGC |
-XX:MaxGCPauseMills | G1最大停顿时间 | 暂停时间不能太小,太小会导致G1跟不上垃圾产生的速度,最终退化成Full GC.所以对正么参数的调优是一个持续的过程,逐步调整到最佳状态 |
-XX:ConcGCThreads | 并发垃圾收集器使用的线程数量 | |
-XX:G1MixedGCLiveThresholdPercent | 混合垃圾回收周期中要包括的旧区域设置占用率阈值 | 默认65% |
-XX:G1MixedGCCountTarget | G1回收分区时最大混合式GC周期数 | 默认值为8 |
-XX:G1OldCSetRegionThresholdPercent | 设置混合垃圾回收期间要回收的最大旧区域数 | 默认值为10 |
二、常用命令
2.1 jps
查看进程
The jps command lists the instrumented Java HotSpot VMs on the target system. The command is limited to reporting information on JVMs for which it has the access permissions.
2.2 jinfo
- 实时查看和调整JVM参数
The jinfo command prints Java configuration information for a specified Java process or core file or a remote debug server. The configuration information includes Java system properties and Java Virtual Machine (JVM) command-line flags.
- 查看
格式:jinfo -flag <name> <PID> 如:jinfo -flag UserG1GC 126492
- 修改
只有被标记为manageable的参数才可以使用jinfo实时修改
格式: 1. jinfo -flag [+/-]<name> <PID> 2. jinfo -flag <name>=<value> <PID> 如 jinfo -flag HeapDumpPath=log/heap.hprof 126492
2.3 jstat
- 查看类装载信息
jstat -class PID 1000 10 查看某个java进程的类装载信息,每1000毫秒输出一次,共输出10 次
- 查看垃圾收集信息
jstat -gc PID 1000 10
2.4 jstack
- 查看线程堆栈信息
jstack PID
- 排查死锁案例
1. 死锁代码
public class DeadLockDemo implements Runnable { boolean flag; public DeadLockDemo(boolean flag) { this.flag = flag; } @Override public void run() { if (flag) { while (true) { synchronized (MyLock.lock1) { System.out.println(Thread.currentThread().getName() + ": 获得lock1"); synchronized (MyLock.lock2) { System.out.println(Thread.currentThread().getName() + ": 获得lock2"); } } } } else { while (true) { synchronized (MyLock.lock2) { System.out.println(Thread.currentThread().getName() + ": 获得lock1"); synchronized (MyLock.lock1) { System.out.println(Thread.currentThread().getName() + ": 获得lock2"); } } } } } public static void main(String[] args) { Thread thread1 = new Thread(new DeadLockDemo(true), "线程1"); Thread thread2 = new Thread(new DeadLockDemo(false), "线程2"); thread1.start(); thread2.start(); } } class MyLock { public static final Object lock1 = new Object(); public static final Object lock2 = new Object(); }
2. 运行结果
3. jstack分析
Found one Java-level deadlock: ============================= "线程2": waiting to lock monitor 0x000000001c5db238 (object 0x000000076bc16bc0, a java.lang.Object), which is held by "线程1" "线程1": waiting to lock monitor 0x000000001c5ddac8 (object 0x000000076bc16bd0, a java.lang.Object), which is held by "线程2" Java stack information for the threads listed above: =================================================== "线程2": at DeadLockDemo.run(DeadLockDemo.java:27) - waiting to lock <0x000000076bc16bc0> (a java.lang.Object) - locked <0x000000076bc16bd0> (a java.lang.Object) at java.lang.Thread.run(Thread.java:748) "线程1": at DeadLockDemo.run(DeadLockDemo.java:18) - waiting to lock <0x000000076bc16bd0> (a java.lang.Object) - locked <0x000000076bc16bc0> (a java.lang.Object) at java.lang.Thread.run(Thread.java:748) Found 1 deadlock.
2.5 jmap
- 生成堆转储快照
The jmap command prints shared object memory maps or heap memory details of a specified process, core file, or remote debug server.
- 打印堆内存相关信息
jmap -heap PID
- dump出堆内存相关信息
jmap -dump:format=b,file=heap.hprof PID
- 当发生堆内存溢出时,自动生成dump文件
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof