当前位置:   article > 正文

Java进程CPU占用率高的排查和常见解决方案_cpu使用率高java

cpu使用率高java

当系统出现卡顿或者应用程序的响应速度非常慢,就可能要考虑到服务器上排查一番,以下是我常用的排查流程:

1top:观察占用CPU或者MEN(内存)使用情况最高的进程,记录PID;
TIP:
(1)、“1” 显示出多个逻辑CPU使用情况;
(2)、“X” 高亮显示CPU列,并排序,"Z"红色展示;
(3)、“shift + <” 或者 “shift + >” 变更高亮的列;
(4)、“F”配合 “空格”指定需要展示的列;
(5)、“S”设置刷新的间隔时间;

2top -p PID:观察该PID对应进程的占用情况。“shift + h” 开启线程显示,观察CPU占用较高的线程有哪些,记录对应TID;

3printf "%x\n" TID :将线程对应PID转为 16进制数(TID16);

4jstack PID | grep -A 30 "nid=0x + TID16" :查看该线程的堆栈信息;

5、通过线程的堆栈信息,定位到CPU占用过高的代码,分析其原因。
TIP:
(1)、通常可以结合jstat来分析JVM中的内存信息;(如jstat -gcutil PID 1000 10jstat -gc PID 1000 10jstat -gccause PID 1000 10
(2)、jmap -heap PID来查看整个JVM内存状态 ;(要注意的是在使用CMS GC情况下,jmap -heap的执行有可能会导致JAVA进程挂起)
(3)、jmap -histo PID 查看JVM堆中对象详细占用情况;
(4)、jmap -dump:format=b,file=文件名 [pid]导出整个JVM中内存信息。


常见服务器CPU过高的问题原因和对应解决方案:

1、方法中存在读写文件流的操作,高并发时每个请求产生一个文件流,导致系统CPU急增。

解决方案:
从线程栈日志信息中,找出导致CPU高的线程方法。读写文件流操作移出方法中,避免每次请求都产生一个文件流。

2、方法中使用了多线程,未使用连接池或使用了Executors.newCachedThreadPool()创建的接连池,高并发时创建出过多的后台线程。

解决方案:
a、使用jstack命令统计出线程数量;
b、找出程序中创建线程代码;
c、使用Executors.newFixedThreadPool(thread_size)创建固定数量的线程池(线程数固定,无法无收),或者使用new ThreadPoolExecutor(coreSize, maxSize, 60L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())直接构造线程池。

3、发现是gc线程导致的CPU问题比较费时

解决方案:
a、查看一下gc策略是否合理;
b、用命令jmap -histo [PID] 分析是哪个类占用内存比较多,分析出可能存在内存泄露的地方;
c、jvm内存调优,可使用Jconsole、visalvm、probe等工具查看java虚拟机中方法区、堆区(新生代、幸存代、老年代)、线程栈的内存分配,根据实际情况进行优化。

4、代码中存在死循环、死锁

解决方案:
直接通过jstack获取到出问题的线程的堆栈信息,分析代码逻辑。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/206945
推荐阅读
相关标签
  

闽ICP备14008679号