https://wangcw.blog.csdn.net/article/details/86242263?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control
以下验证
当系统出现卡顿或者应用程序的响应速度非常慢,就可能要考虑到服务器上排查一番,以下是我常用的排查流程:
1、top:观察占用CPU或者MEN(内存)使用情况最高的进程,记录PID;
TIP:
(1)、“1” 显示出多个逻辑CPU使用情况;
(2)、“X” 高亮显示CPU列,并排序,"Z"红色展示;
(3)、“shift + <” 或者 “shift + >” 变更高亮的列;
(4)、“F”配合 “空格”指定需要展示的列;
(5)、“S”设置刷新的间隔时间;
2、top -Hp PID:观察该PID对应进程的占用情况。“shift + h” 开启线程显示,观察CPU占用较高的线程有哪些,记录对应TID;
3、printf "%x " TID :将线程对应PID转为 16进制数(TID16);
4、jstack -F PID | grep -A 30 "nid=0x + TID16" > /java/PID.txt:查看该线程的堆栈信息;
jstack -F PID > /java/PID.txt:查看该线程的堆栈信息;
5、通过线程的堆栈信息,定位到CPU占用过高的代码,分析其原因。
TIP:
(1)、通常可以结合jstat来分析JVM中的内存信息;(如jstat -gcutil PID 1000 10 、jstat -gc PID 1000 10、jstat -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获取到出问题的线程的堆栈信息,分析代码逻辑。
————————————————
版权声明:本文为CSDN博主「JdbcUtils」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_33404395/article/details/86242263