java线上cpu、内存问题排查方法
一、线程
查进程中占用cpu高的线程
ps -mp xxxxx -o THREAD,tid,time | sort -rn
将线程的id从10位转到16位,可以在下面jstack中找到对应线程
输出线程详细信息(-l 多输出一些锁的信息)
jstack -l xxxxx | grep xxx -A 30 > 1.txt
查找处于RUNNABLE的和业务相关的线程
dstat
性能检测工具
cpu:hiq、siq分别为硬中断和软中断次数
system:int、csw分别为系统的中断次数(interrupt)和上下文切换(context switch)
二、内存
查内存信息
jstat -gcutil xxxxx 2000 10
查内存dump信息
jmap -dump:live,format=b,file=/home/dump xxxxx
取到的dump文件在eclipse的mat插件视图中打开(mat可以在Eclipse Maketplace中下载,注意勾选安装所有依赖插件)
Leak Suspects是可能内存泄漏的地方,Histogram是内存中的对象、对象个数和大小,Dominator Tree是线程和线程下对象占用的空间
在Histogram中找到最大的对象,右键List Objects --> with incoming reference查看被引用的列表,找到最大的对象,右键Merge Shortest Paths to GC Roots --> exclude all phantom/weak/soft etc. reference去除虚引用、弱引用、软引用只留下强引用,看导致对象无法被GC的强引用是什么
三、连接
查连接状态统计
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
查看连接某端口最多的ip
netstat -ntu | grep :80 | awk '{print $5}' | cut -d: -f1 | awk '{++ip[$1]} END {for(i in ip) print ip[i],"\t",i}' | sort -nr
四、句柄
查linux最大文件句柄数(open files)
ulimit -a
查当前句柄/进程数量
lsof -n|awk '{print $2}'| sort | uniq -c | sort -nr | head
查单个进程的句柄
lsof -p 2333
五、抓包
查看网卡
ifconfig
抓包并保存
tcpdump tcp -i eth0 -s 0 and host xxx.xxx.xxx.xxx and port xxxx -w log.pcap -i:只抓经过接口eth0的包 -s 0:抓到完整的数据包 -w:保存在文件