欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

linux排查CPU或内存占用高问题(JAVA程序导致linux服务器CPU过高和内存过高)

程序员文章站 2022-07-14 13:58:28
...

最近生产环境经常发生CPU和内存异过高的情况,以前一般排查的也是一些死锁问题,排查死锁的时候直接打印程序的堆栈信息,然后查看线程的各种状态,差不多都能猜到问题所在,这两天cpu和内存问题刚开始也是直接打印堆栈信息,然后发现堆栈信息太多,很难定位到是什么导致了cpu和内存问题,虽然在堆栈文件里面找到很多自己写的业务代码,但是因为执行的线程比较多,查询起来比较费劲(基本上来说除非交易量很大,应用支持不了需要扩容,大部分的问题都是我们自己写的业务代码导致的。),网上对这些排查的方式也比较多了,这里记录一下自己的操作记录,生产环境我们也操作不了,我们提供操作方法,其他的就给运维去处理 了。

参考链接:这类问题还是比较成熟的,网上方案也很多,自己动手做一遍才能记住。
https://blog.csdn.net/notsaltedfish/article/details/80209538
https://blog.csdn.net/xgjianstart/article/details/53427420
https://blog.csdn.net/qq_24949727/article/details/70738723
https://www.iteye.com/blog/host-2365495
https://blog.csdn.net/daiyudong2020/article/details/52760846
https://www.cnblogs.com/lixiuyuan999/p/6384167.html

第一步:找出最占线程和CPU的进程

既然是CPU和内存高导致的问题,那么第一步肯定是找出占CPU和线程最高的进程了

命令

  1. 执行top命令
  2. 按P(注意是大写的P,直接按shift+p也可以)–>以 CPU 占用率大小的顺序排列进程列表
  3. 按M(注意是大写的M,直接按shift+m也可以) --> 以内存占用率大小的顺序排列进程列表
  4. 图中的第一列PID,就是占用的进程ID,这里是进程不是线程,后面都会用到这个进程ID的。

linux排查CPU或内存占用高问题(JAVA程序导致linux服务器CPU过高和内存过高)

第二步:定位到哪个服务(这一步不需要,我只是想知道是哪个应用占用的CPU和内存)

这里执行命令中的4863就是第一步中获取到的PID。

[aaa@qq.com ~]$ ps -ef |grep 4863

linux排查CPU或内存占用高问题(JAVA程序导致linux服务器CPU过高和内存过高)

第三步:先打印堆栈信息

执行jstack 16799 > dump,把堆栈信息输出到文本文件里面,方便后面查找,图中的命令指示为了方便演示,我们以前定位死锁的时候基本就是把堆栈信息打印就结束了,问题就是你会发现这个堆栈文件很长,要一个一个的查看,看的头疼,所以我们只需要看我们需要看的就行了,我们需要看占CPU或内存高的线程的堆栈就行了。
linux排查CPU或内存占用高问题(JAVA程序导致linux服务器CPU过高和内存过高)

第四步:通过进程找出最占CPU或内存的线程

应用程序占用CPU或内存的都是线程在执行,所以关键点是找到线程的堆栈。
命令格式top -Hp pid |grep -v pid
这里的pid还是最上面通过top找出来的pid,后面添加grep -v只是排除进程自身的线程(这句话貌似不准确)。
命令操作步骤

  1. 执行top -Hp pid |grep -v pid命令
  2. 按P(注意是大写的P,直接按shift+p也可以)–>以 CPU 占用率大小的顺序排列进程列表
  3. 按M(注意是大写的M,直接按shift+m也可以) --> 以内存占用率大小的顺序排列进程列表
  4. 图中的第一列PID,是上面这个进程的线程ID,这里是名字虽然显示PID,其实我们找出来是线程ID,就是我们所说的tid
[aaa@qq.com ~]$ top -Hp 4196 |grep -v 4196

linux排查CPU或内存占用高问题(JAVA程序导致linux服务器CPU过高和内存过高)

第五步:把第四步找到的线程ID转换成16进制,默认显示的10进制。

执行 printf ‘%x\n’ 4199来进行转换,这里的4199就是上面的PID(我们一般叫做TID,因为这里显示的线程号)

[aaa@qq.com ~]$ printf '%x\n' 4249
1099
[aaa@qq.com ~]$ printf '%x\n' 4199
1067
[aaa@qq.com ~]$ 

第六步:就是根据转换之后的PID到堆栈信息里面查找了。

使用转换成16进制的数字去堆栈信息里面找,可以直接使[aaa@qq.com ~]$ jstack 4863 |grep -10ab 1309命令去查看,最好还是把堆栈文件打印出来,然后用vi进去,使用查找命令进行查看。
linux排查CPU或内存占用高问题(JAVA程序导致linux服务器CPU过高和内存过高)

总结

生产上出CUP和内存问题,基本上都是按照这个思路去找的,但是找到了之后还需要分析代码的,常规思路CPU过高一般是计算型任务执行很久,比如说SQL写的不好查询不出来呀,内存问题就是大量new对象或者读取大文件,尤其在上传execl表格的时候,其次就是注意查询东西,返回东西的时候一般要控制好返回的数量,不要一次性查询出来然后通过网络返回,这种操作在并发稍微大一点的时候就会出现各种问题,一台机器上,一个应用程序的问题可能引起整台服务器的其他应用都会出现问题。