GuangchaoSun's Blog

jvm调优常用命令

获取JVM设置默认值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[ccag@devtbcwas ~]$ java-XX:+PrintFlagsFinal -version|grep -i HeapSize
uintx ErgoHeapSizeLimit = 0 {product}
uintx HeapSizePerGCThread = 87241520 {product}
uintx InitialHeapSize := 262144000 {product}
uintx LargePageHeapSizeThreshold = 134217728 {product}
uintx MaxHeapSize :=4164943872 {product}
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build25.151-b12, mixed mode)

jps(JVM Process Status Tool)-显示指定系统内所有HotSpot虚拟机进程

1
2
3
4
5
[ccag@devtbcwas ~]$ jps -l -m
5584 sun.tools.jps.Jps -l -m
4055 com.sunyard.ag.server.Server

jstat(JVM statics Monitoring)

用于监视虚拟机运行时状态信息的命令,它可以显示出虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。

1.监视类装载、卸载数量、总空间以及耗费的时间

1
2
3
4
5
[ccag@devtbcwas ~]$ jstat -class 4055
Loaded Bytes Unloaded Bytes Time
2944 6180.0 0 0.0 1.25

2.输出JIT编译过的方法数量耗时等

1
2
3
4
5
[ccag@devtbcwas ~]$ jstat -compiler 4055
Compiled Failed Invalid Time FailedType FailedMethod
1565 0 0 2.25 0

3.垃圾收集统计概述,附加最近两次垃圾收集事件的原因

1
2
3
4
5
[ccag@devtbcwas ~]$ jstat -gccause 4055
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC
0.00 93.72 63.02 0.05 97.03 92.00 1 0.020 0 0.000 0.020 AllocationFailure No GC

4.每隔2000ms输出4055进程的gc情况,一共输出1次

1
2
3
4
5
[ccag@devtbcwas ~]$ jstat -gc 4055 2000 1
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
10240.0 10240.0 0.0 9596.9 64512.0 40654.4 171008.0 80.0 19328.0 18754.3 2432.02237.3 1 0.020 0 0.000 0.020

5.输出该进程的Java堆各区域使用的最大、最小空间

1
2
3
4
5
[ccag@devtbcwas ~]$ jstat -gccapacity 4055
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC
84992.0 1355776.0 84992.0 10240.0 10240.0 64512.0 171008.0 2711552.0 171008.0 171008.0 0.0 1067008.0 19328.0 0.0 1048576.0 2432.0 1 0

6.已使用空间占总空间的百分比

1
2
3
4
5
6
7
8
[ccag@devtbcwas ~]$ jstat -gcutil 4055
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 93.72 63.02
0.05 97.03 92.00
1 0.020 0
0.000 0.020

jmap(JVM Memory Map)

该命令用于生成heapdump文件,如果不使用这个命令,还可以使用-XX:+HeapDumpOnOutOfMemoryError参数让虚拟机出现OOM的时候自动生成dump文件。

jmap不仅能生成dump文件,还可以查询finalize执行队列、Java堆和永久代的详细信息,如当前使用率、当前使用的是哪种收集器等。

1.打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况,可以用来判断内存的使用情况以及垃圾回收算法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
[ccag@devtbcwas ~]$ jmap -heap 4055
Attaching to process ID 4055, pleasewait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.151-b12
using thread-local object allocation.
Parallel GC with 8 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize =4164943872 (3972.0MB)
NewSize =87031808 (83.0MB)
MaxNewSize =1388314624 (1324.0MB)
OldSize =175112192 (167.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 Space:
capacity = 66060288 (63.0MB)
used = 41630152(39.70160675048828MB)
free = 24430136(23.29839324951172MB)
63.018423413473464% used
From Space:
capacity = 10485760 (10.0MB)
used = 9827256(9.372001647949219MB)
free = 658504(0.6279983520507812MB)
93.72001647949219% used
To Space:
capacity = 10485760 (10.0MB)
used = 0 (0.0MB)
free = 10485760 (10.0MB)
0.0% used
PS Old Generation
capacity = 175112192 (167.0MB)
used = 81936(0.0781402587890625MB)
free = 175030256(166.92185974121094MB)
0.046790574125187126% used
8022 interned Strings occupying 638528bytes.

2.Dump到文件,format指定输出格式,live指明是活着的对象,file指定文件名

1
2
3
4
5
[ccag@devtbcwas AgServer]$ jmap-dump:live,format=b,file=dump.hprof 31729
Dumping heap to/home/ccag/AgServer/dump.hprof ...
Heap dump file created

3.打印等待回收对象的信息

1
2
3
4
5
6
7
8
9
10
11
[ccag@devtbcwas AgServer]$ jmap -finalizerinfo31729
Attaching to process ID 31729, pleasewait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.151-b12
Number of objects pending for finalization:0

4.打印堆的对象统计,包括对象数,内存大小等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
[ccag@devtbcwas AgServer]$ jmap -histo:live31729 | more
num #instances #bytes class name
----------------------------------------------
1: 14806 993736 [C
2: 1087 494824 [B
3: 2960 349120 java.lang.Class
4: 14481 347544 java.lang.String
5: 2072 274920 [I
6: 2330 158384 [Ljava.lang.Object;
7: 3987 127584 java.util.HashMap$Node
8: 3894 124608 java.util.concurrent.ConcurrentHashMap$Node
9: 972 85536 java.lang.reflect.Method
10: 206 47528 [Ljava.util.HashMap$Node;
11: 2397 38352 java.lang.Object
12: 774 34920 [Ljava.lang.String;
13: 847 33880 java.util.LinkedHashMap$Entry
14: 450 32400 java.lang.reflect.Field
15: 49 31600 [Ljava.util.concurrent.ConcurrentHashMap$Node;
16: 1037 23776 [Ljava.lang.Class;
17: 508 20320 java.lang.ref.SoftReference
18: 279 18000 [S
19: 31 15936 [Loracle.jdbc.driver.OracleSqlReadOnly$ODBCAction;
20: 317 15216 java.util.HashMap
21: 412 13184 java.lang.ref.WeakReference
22: 226 12656 java.lang.invoke.MemberName
23: 748 11968 java.lang.Integer
24: 373 11936 java.util.Hashtable$Entry
25: 146 11680 java.lang.reflect.Constructor
26: 341 10912 sun.misc.FDBigInteger
27: 186 10416 java.lang.Class$ReflectionData

jstack

jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法的堆栈的集合,生成线程快照的目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。

除堆栈外,显示关于锁的附加信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
[ccag@devtbcwas AgServer]$ jstack -l 31729
2018-05-14 09:50:25
Full thread dump Java HotSpot(TM) 64-BitServer VM (25.151-b12 mixed mode):
"pool-1-thread-4" #22 prio=5os_prio=0 tid=0x00007fe35c00b000 nid=0x7c6f waiting on condition[0x00007fe374dcb000]
java.lang.Thread.State: TIMED_WAITING (parking)
​ atsun.misc.Unsafe.park(Native Method)
​ -parking to wait for <0x00000006c7df9820> (a java.util.concurrent.SynchronousQueue$TransferStack)
​ atjava.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
​ atjava.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
​ atjava.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
​ atjava.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
​ atjava.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1073)
​ atjava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
​ atjava.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
​ atjava.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
​ -None
"pool-1-thread-3" #21 prio=5os_prio=0 tid=0x00007fe35c00a000 nid=0x7c59 waiting on condition[0x00007fe3757d6000]
java.lang.Thread.State: TIMED_WAITING (parking)
​ atsun.misc.Unsafe.park(Native Method)
​ -parking to wait for <0x00000006c7df9820> (ajava.util.concurrent.SynchronousQueue$TransferStack)
​ atjava.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
​ atjava.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
​ atjava.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
​ atjava.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
​ atjava.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1073)
​ atjava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
​ atjava.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
​ atjava.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
​ -None
"Attach Listener" #20 daemonprio=9 os_prio=0 tid=0x00007fe380001000 nid=0x7c2c waiting on condition[0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
​ -None
"oracle.jdbc.driver.BlockSource.ThreadedCachingBlockSource.BlockReleaser"#19 daemon prio=4 os_prio=0 tid=0x00007fe344321000 nid=0x7c13 in Object.wait()[0x00007fe3750cc000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
​ atjava.lang.Object.wait(Native Method)
​ -waiting on <0x00000006c7c2ae68> (aoracle.jdbc.driver.BlockSource$ThreadedCachingBlockSource$BlockReleaser)
​ atoracle.jdbc.driver.BlockSource$ThreadedCachingBlockSource$BlockReleaser.run(BlockSource.java:327)
​ -locked <0x00000006c7c2ae68> (aoracle.jdbc.driver.BlockSource$ThreadedCachingBlockSource$BlockReleaser)
Locked ownable synchronizers:
​ -None

常见问题的定位:

频繁GC问题或内存溢出问题

  1. 使用jps查看线程ID
  2. 使用jstat -gc 3331 2000 20查看gc情况,一般比较关注PERM区的情况,查看GC的增长情况。
  3. 使用jstat -gccause额外输出上次GC原因
  4. 使用jmap -dump:format=b,file=heapDump 3331生成堆转储文件
  5. 使用jhat或者可视化工具(Eclipse Memory Analyzer 、IBM HeapAnalyzer)分析堆情况。
  6. 结合代码解决内存溢出或泄露问题。