侧边栏壁纸
博主头像
Sir丶雨轩博主等级

一个90的萌新码农,热爱编程热爱生活 编程交流群:875477818

  • 累计撰写 48 篇文章
  • 累计创建 81 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

记一次线上环境CPU爆炸问题排查

Sir丶雨轩
2019-09-19 / 0 评论 / 1 点赞 / 116 阅读 / 2,010 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2021-12-23,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

问题是这样的,我们的测试反馈线上的环境特别卡说操作不了

首先我打开网站发现根本访问不了 然后登录了宝塔(服务器管理软件)发现CPU的负载处于100%的爆满状态,接下来就开始紧张刺激的寻找问题了

第一步:找到运行中Java程序的PID

我们有以下两种方式

1.jps  可以获取当前正在运行的所有Java程序的pid

QQ截图20190919160141.png

我们可以看到运行了两个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

这个类占用了绝大部分内存,这肯定是不合理的

我们查看堆栈可以找到具体的出错代码


至此我们已经基本上找到了问题,

1

评论区