linux下jvm问题排查
前言
最近几天,运维告诉我刚上线的java服务占用内存过高。
下面讲述排查问题的具体过程
问题排查步骤
-
进程ID: jps [ options ][ hostid ] 使用jps:jps -l 使用ps:ps aux | grep tomat 虚拟机统计信息监视工具:jstat: jstat [ option vmid [interval[s|ms][count]] ] jstat -gcutil pid 1000 意思是每1000毫秒查询一次,一直查。gcutil的意思是已使用空间站总空间的百分比
-
Java内存影像工具:jmap: jmap [ option ] vmid jmap -histo:live pid jmap -histo:live pid | head -7
-
生成离线文件
$ jmap -dump:live,format=b,file=pid.hprof pid -
MAT分析工具
-
启动项目时加入
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/java/dump分析内存溢出时的具体内容
排查问题
-
通过
top命令找到占用内存最多的进程$ top
-
通过
top -Hp pid查看线程的详细情况,例如上面3231进程$ top -Hp 3231
我们就分析红线标注的线程
-
通过
jstack pid >> pid.txt命令,将线程栈输出到txt文件,例如3231进程$ jstack 3231 >> 3231.txt输出到
3231.txt文件-rw-rw-r-- 1 work work 48292 Oct 30 17:35 3231.txt -
我们以第
2步的红线标注线程为例将
3239转换为16进制,转换命令为printf "%x\n" pid$ printf "%x\n" 3239输出
ca7 -
在
3231.txt文件中寻找线程为ca7的信息$ cat 3231.txt | grep ca7输出
"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f627c13b000 nid=0xca7 waiting on condition [0x0000000000000000]也可以使用
grep -C或者vim 3231.txt文件查看 -
通过具体线程的信息即可分析问题的关键所在
内存分析常用工具(扩展)
-
jmap:用来查看堆内存使用状况,一般结合jhat使用
-
jstack:主要用来查看某个Java进程内的线程堆栈信息语法
jstack [option] pid -
jstat:主要用来查看某个Java进程内的线程堆栈信息我常用的命令是
jstat -gcutil pid interval,例如$ jstat -gcutil 3231 1000每10秒刷新一次
jvm的gc信息 -
jps:主要用来输出JVM中运行的进程状态信息OPTION
-q: 不输出类名、Jar名和传入main方法的参数- m:输出传入main方法的参数-l:输出main类或Jar的全限名-v:输出传入JVM的参数
总结
本文主要讲述的是对占用内存或者cpu过高的进程进行分析并找到问题所在的思路。