问题是这样的,我们的测试反馈线上的环境特别卡说操作不了
首先我打开网站发现根本访问不了 然后登录了宝塔(服务器管理软件)发现CPU的负载处于100%的爆满状态,接下来就开始紧张刺激的寻找问题了
第一步:找到运行中Java程序的PID
我们有以下两种方式
1.jps 可以获取当前正在运行的所有Java程序的pid
我们可以看到运行了两个jar 一个jps是我们刚执行的jps命令
首先我们要确定具体哪一个程序出的问题,我们可以使用以下命令
ps -ef|grep jar
来获得所有运行中的jar的pid,命令行等信息
ok 至此我们已经能得到想要排查问题的程序的pid了。
第一步:
jstack pid >> java.txt 导出指定进程的线程栈
第二步:
top -H -p PID 查看对应进程的哪个线程占用CPU过高。
第三步:
printf "%x\n" tid 将需要的线程ID转换为16进制格式
第四步:
jstack pid |grep tid -A 30 打印线程的堆栈信息
或者下载下来第一步导出的java.txt文件 在里面搜索16进制的线程id
通过线程栈我们可以清楚的看到,是两个gc的线程卡死了
我们可以通过第二步的命令来进行详细信息的查看,比如这个进程持续了多久
PS:这个图是在网上找的可能跟以上的tid不一致请忽略。
我们可以看到这个线程已经持续了接近两个小时,这肯定是有问题的
使用以下命令查看进程的内存使用情况
jstat -gcutil 14063 2000 10
[ylp@ylp-web-01 ~]$ jstat -gcutil 14063 2000 10
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 0.00 100.00 99.99 26.31 42 21.917 218 1484.830 1506.747
0.00 0.00 100.00 99.99 26.31 42 21.917 218 1484.830 1506.747
0.00 0.00 100.00 99.99 26.31 42 21.917 219 1496.567 1518.484
0.00 0.00 100.00 99.99 26.31 42 21.917 219 1496.567 1518.484
0.00 0.00 100.00 99.99 26.31 42 21.917 219 1496.567 1518.484
0.00 0.00 100.00 99.99 26.31 42 21.917 219 1496.567 1518.484
0.00 0.00 100.00 99.99 26.31 42 21.917 219 1496.567 1518.484
0.00 0.00 100.00 99.99 26.31 42 21.917 220 1505.439 1527.355
0.00 0.00 100.00 99.99 26.31 42 21.917 220 1505.439 1527.355
0.00 0.00 100.00 99.99 26.31 42 21.917 220 1505.439 1527.355
从输出信息可以看出,Eden区内存占用100%,Old区内存占用99.99%,Full GC的次数高达220次,并且频繁Full GC,Full GC的持续时间也特别长,平均每次Full GC耗时6.8秒(1505.439/220)。根据这些信息,基本可以确定是程序代码上出现了问题,可能存在不合理创建对象的地方
这个时候我们可以dump下Java运行时的内存进行分析
查看整个JVM内存状态
jmap -heap [pid]
要注意的是在使用CMS GC 情况下,jmap -heap的执行有可能会导致JAVA 进程挂起
查看JVM堆中对象详细占用情况
jmap -histo [pid]
导出整个JVM 中内存信息
jmap -dump:format=b,file=文件名 [pid]
内存分析工具
eclipse Memory Analyzer
Eclipse 提供的一个用于分析JVM 堆Dump文件的插件。借助这个插件可查看对象的内存占用状况,引用关系,分析内存泄露等。
http://www.eclipse.org/mat/
用此工具打开我们刚才dump下的内存文件
我们可以看到
TaskThread
这个类占用了绝大部分内存,这肯定是不合理的
我们查看堆栈可以找到具体的出错代码
至此我们已经基本上找到了问题,
评论区