JVM调优排错(解析&实际案例)

前言

本案例只是简单介绍JVM排查工具,调优措施,以及普遍示例简单解析。(更完整命令可以参考:docs.oracle.com/javase/7/do…)

一. 常用工具

  1. jmap

jmap命令是一个可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本。打印出某个java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些对象,及其数量)。
使用示例:

  1. jmap -histo $PID –> 显示堆中对象的统计信息
    image.png

其中instance表示元素出现的个数,bytes表示元素所占内存大小(单位kb)

  1. jamp -heap $PID –> 显示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
js复制代码Attaching to process ID 31370, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.45-b02

using thread-local object allocation.
Parallel GC with 4 thread(s)

Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 492830720 (470.0MB)
NewSize = 10485760 (10.0MB)
MaxNewSize = 164102144 (156.5MB)
OldSize = 20971520 (20.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 = 7864320 (7.5MB)
used = 5038400 (4.80499267578125MB)
free = 2825920 (2.69500732421875MB)
64.06656901041667% used
From Space:
capacity = 5767168 (5.5MB)
used = 131072 (0.125MB)
free = 5636096 (5.375MB)
2.272727272727273% used
To Space:
capacity = 6291456 (6.0MB)
used = 0 (0.0MB)
free = 6291456 (6.0MB)
0.0% used
PS Old Generation
capacity = 117964800 (112.5MB)
used = 78530512 (74.89253234863281MB)
free = 39434288 (37.60746765136719MB)
66.57113986545139% used
  1. jmap -dump:live,format=b,file=dumpfile $PID –> 生成堆转储快照dump文件

或jmap -dump:live,format=b,file=heapdump.hprof $PID,hprof方便通过mat解析。live子选项是可选的。如果指定了live子选项,堆中只有活动的对象会被转储。(执行较为耗时)

  1. jstack

jstack是java虚拟机自带的一种堆栈跟踪工具。常用于分析线程问题(如线程间死锁[deadLock])
使用示例:

  1. jstack -l $PID > /tmp/dump/jstack.log –> 导出堆栈信息

-l :会打印出额外的锁信息
image.png

  1. 找出java进程中消耗CPU最多的线程TID
  • 结合top命令可以查出占用CPU最高的线程: top -H -p pid

详细输出可以使用:ps p {pid}-L -o pcpu,pid,tid,time,tname,cmd

  • 将TID转化成十六进制: printf 0x%x n
  • 从jstack.log 文件中找出TID对应的16进制数据
  1. jstat

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

  1. jstat -gc $PID –> 获取垃圾回收等信息

image.png

1
2
3
4
5
6
7
8
9
10
js复制代码 结果分析:(C一般是容量,U结尾一般是使用量)
堆内存 = 年轻代 + 年老代 + 永久代
年轻代 = Eden区 + 两个Survivor区
S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used)
EC、EU:Eden区容量和使用量
OC、OU:年老代容量和使用量
PC、PU:永久代容量和使用量
YGC、YGT:年轻代GC次数和GC耗时
FGC、FGCT:Full GC次数和Full GC耗时
GCT:GC总耗时

clipboard.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
js复制代码引言:JVM配置中除了常用的xmx,xms
-Xmn、-XX:NewRatio、-XX:SurvivorRatio:

- -Xmn

**设置新生代大小**

- -XX:NewRatio

    新生代(eden+2*s)和老年代(不包含永久区)的比值

        例如:4,表示新生代:老年代=1:4,即新生代占整个堆的1/5

- -XX:SurvivorRatio(幸存代)

    设置两个Survivor区和eden的比值

        例如:8,表示两个Survivor:eden=2:8,即一个Survivor占年轻代的1/10
  1. GC结果分析
    ygc平均耗时=YGCT/YGC(s)=5176.81/469204=0.011s=11ms
    ygc时间间隔=YGC/程序的运行时间
1
2
3
4
5
6
js复制代码如果各项参数设置合理,系统没有超时日志出现,GC频率不高,GC耗时不高,那么没有必要进行GC优化;
如果GC时间超过1〜3 秒,或者频繁G C ,则必须优化。如果满足下面的指标,则一般不需要进行GC;
■ Minor GC执行时间不到50ms;\
■ Minor GC执行不频繁,约10秒一次;\
■ Full GC执行时间不到1s;\
■ Full GC执行频率不算频繁,不低于10分钟1次。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%