应用服务器CPU高性能定位和排查

本课程的主旨及目标

•导致应用CPU高的常见原因

•定位问题的大体思路

•定位问题的具体方法

•实际案例

应用CPU高常见原因

•1.程序计算比较密集

•2. 程序死循环、死锁

•3.程序逻请求堵塞

•4.IO读写太高 (df –h看看磁盘是不是满了)

•5.自创线程没有限制(线程池)

•6.不合理的创建对象,导致频繁GC

定位问题的具体方法

1.不管什么情况先用top命令查看资源消耗,找到消耗大量CPU资源的进程pid,我们一般都是java进程排名第一

 

2.输入top –p pid 来单独监控该进程

 

3.在第2步的监控界面输入H,获取当前进程下的所有线程信息

 

4.找到消耗cpu特别高的线程编号(可能会有多个),这里是6752

5.将第4步得到的线程编号6752转成16进制是1a60,因为jstack输出的线程栈信息中,线程ID是以十六进制展示的。

 

6.切换到jbossuser用户【pid对应的进程用户,这里一般是java进程用户】

 

7.因为没有jstack这个文件的环境变量,所以要先export PATH="$PATH:/opt/wildfly/openjdk/openjdk-1.8.0_92/bin"

8.使用命令 jstack $pid | grep “线程id” –A 30,把信息打印出来【这里的-A 30指的是30行】【线程id:根据第5步得到的1a68在pid线程信息里面去找对应线程内容】,也可以写到文件中,下载下来,通过16进制的线程id来搜索定位代码段。

 

9.通过jstack命令来查看下当前内存状态,解读线程信息,定位具体代码位置,接下来就是找开发人员确认问题,看这段代码是否可以优化。

实际案例

案例一:

定位到cpu过高是IO读写太高 ,接下来就是找开发人员确认这段代码是否可以优化

 

案例二:

两个线程执行过程中,需要对两个对象进行加锁,且加锁的顺序不一致,导致了死锁的产生,简单的修复方法是:对两个对象的加锁顺序一致。

注意:必须有两个可以被加锁的对象才能产生死锁,只有一个不会产生死锁问题

 

案例三:

 

案例四:

 

 

 

案例五:

1.生产环境heap堆内存不断上升导致oom,pst环境复现heap堆内存不断上升。经过分析堆内存创建的windq主题或队列WindqQueue、WindqTopic方式会缓存到连接工厂,缓存的对象并不是根据唯一的key去缓存,而是直接使用对象的引用作缓存,导致jvm无法回收这部分内存(比如新建同一个sendOperationTopic的主题Object1,Object2,Object1和Object2都会缓存到连接工厂)。

2.pst环境百万数据重试发现栈内存溢出,由于递归调用导致,已将递归方法修改为循环的方式去调用。

结果:修改后pst环境内存回收稳定,无连接工厂大对象,堆内存,无栈内存溢出,cpu使用情况稳定。

发现程序异常前通过执行指令,直接生成当前JVM的dump文件,15434是指JVM的进程号

jmap -dump:format=b,file=serviceDump.dat 15434

 

 

 

 

posted @ 2022-03-03 15:43  MLing  阅读(152)  评论(0编辑  收藏  举报