赞
踩
第一步操作:
jmap -dump:format=b,file=/tmp/jmap_heapdump.hprof <pid>
生成DUMP日志-本地java中jvisualvm.exe查看分析
第二步操作:
jstack -l PID >/tmp/gc.log
第三步操作:
1.执行top -c命令,找到cpu最高的进程的id
2.执行top -H -p pid,这个命令就能显示刚刚找到的进程的所有线程的资源消耗情况。找到CPU负载高的线程tid 8627, 把这个数字转换成16进制,21B3(10进制转16进制,用linux命令: printf %x 172)。
3.执行jstack -l pid,拿到进程的线程dump文件。这个命令会打出这个进程的所有线程的运行堆栈。
4.用记事本打开这个文件,搜索“21B3”,就是搜一下16进制显示的线程id。搜到后,下面的堆栈就是这个线程打出来的。排查问题从这里深入。
第四步操作:
- jstat -gccause PID 2000 50 --每2秒执行一次共执行50次
-
- S0 S1 E O P YGC YGCT FGC FGCT GCT LGCC GCC
- 0.00 99.84 12.76 0.92 46.23 1 0.016 0 0.000 0.016 unknown GCCause No GC
######################## 术语分隔符 ########################
- #S0 年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
- #S1 年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
- #E 年轻代中Eden(伊甸园)已使用的占当前容量百分比
- #O old代已使用的占当前容量百分比
- #P perm代已使用的占当前容量百分比
- #YGC 从应用程序启动到采样时年轻代中gc次数
- #FGC 从应用程序启动到采样时old代(全gc)gc次数
- #FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)
- #GCT 从应用程序启动到采样时gc用的总时间(s)
- #LGCC 最后一次GC的原因
- #GCC 当前GC的原因
ps aux|grep java|grep -v grep|head -5|awk '{print $3,$1,$2}'|sort -rn #查询java进程前五的进程并进行排序
GC调优命令:
1.jps
2.jmap
3.Jstack
4.Jinfo
5.Jstat
1.jps
查看jvm应用和端口
2.jmap
此命令可以用来查看内存信息
1) 查看对类的信息
- jmap -histo pid > ./log.txt
- #说明:
- #num:序号
- #instances:实例数量
- #bytes:占用空间大小
- #class name:类名称,[C is a char[],[S is a short[],[I is a int[],[B is a byte[],[[I is a int[][]
2) 查看新生代老年代等内存信息
jmap -heap pid
3)生产dump文件 可供一些工具来分析jvm 例如JProfiler
- jmap -dump:format=b,file=test.hprof pid
- #此命令慎用,如果在生产中需要生成dump文件,最好将此服务器或应用摘除集群,如果没有高可用最好不要使用此命令。
3.Jstack
查看jvm信息,可以查看死锁
4.Jinfo
查看正在运行的Java应用程序的扩展参数#查看jvm的参数
Jinfo pid
5.Jstat
jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。
jstat -gc pid
说明:
S0C:第一个幸存区的大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
OC:老年代大小
OU:老年代使用大小
MC:方法区大小(元空间)
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间,单位s
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间,单位s
GCT:垃圾回收消耗总时间,单位s
具体分析
JVM运行情况预估
用 jstat gc -pid 命令可以计算出如下一些关键数据,有了这些数据就可以采用之前介绍过的优化思路,先给自己的系统设置一些初始性的JVM参数,比如堆内存大小,年轻代大小,Eden和Survivor的比例,老年代的大小,大对象的阈值,大龄对象进入老年代的阈值等。
年轻代对象增长的速率
可以执行命令 jstat -gc pid 1000 10 (每隔1秒执行1次命令,共执行10次),通过观察EU(eden区的使用)来估算每秒eden大概新增多少对象,如果系统负载不高,可以把频率1秒换成1分钟,甚至10分钟来观察整体情况。注意,一般系统可能有高峰期和日常期,所以需要在不同的时间分别估算不同情况下对象增长速率。
Young GC的触发频率和每次耗时
知道年轻代对象增长速率我们就能够根据eden区的大小推算出Young GC大概多久触发一次,Young GC的平均耗时可以通过 YGCT/YGC公式算出,根据结果我们大概就能知道系统大概多久会因为Young GC的执行而卡顿多久。
每次Young GC后有多少对象存活和进入老年代
这个因为之前已经大概知道Young GC的频率,假设是每5分钟一次,那么可以执行命令 jstat -gc pid 300000 10 ,观察每次结果eden,survivor和老年代使用的变化情况,在每次gc后eden区使用一般会大幅减少,survivor和老年代都有可能增长,这些增长的对象就是每次Young GC后存活的对象,同时还可以看出每次Young GC后进去老年代大概多少对象,从而可以推算出老年代对象增长速率。
Full GC的触发频率和每次耗时
知道了老年代对象的增长速率就可以推算出Full GC的触发频率了,Full GC的每次耗时可以用公式 FGCT/FGC 计算得出。
优化思路其实简单来说就是尽量让每次Young GC后的存活对象小于Survivor区域的50%,都留存在年轻代里。尽量别让对象进入老年代。尽量减少Full GC的频率,避免频繁Full GC对JVM性能的影响。
作者:elsen_zhao
链接:https://www.jianshu.com/p/96cc512acc32
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。