问题描述
系统正式上线后,运行一段时间,经常会出现cpu过高问题,导致服务器性能急剧下降,可能是高并发,外部攻击,代码缺陷所致
问题定位
编写测试类HighCPUTest.java
, 编译运行
public class HighCPUTest {
public static void main(String[] args) {
while (true) {
}
}
}
查看进程运行状态
Linux
使用top
命令
PID:进程号(3610)
%CPU: 进程CPU使用率(99.8)
Windows
打开任务管理器
查看PID CPU使用率信息
查看线程运行状态
Linux
使用top -Hp
命令
PID:线程号(3611)
%CPU:线程CPU使用率(99.9)
可以看到JAVA进程3610所有线程信息,通过CPU使用率定位到线程3611可能存在问题
Windows
Windows系统没有自带线程查看工具,需要下载安装,可视化工具推荐 ProcessExplorer
进程 PID[316] CPU使用率过高
查看线程信息 右键 > Properties... > Threads
线程TID[3816] CPU使用率过高
jstack命令输出运行栈信息
命令简介:
jstack是JDK自带的一种堆栈跟踪工具,如果线上环境使用JRE,需要安装JDK
Linux
jstack PID
输出代码运行栈信息,保存到文件中
$ jstack 3610 > jstack.3610
10进制线程号3611
转换为16进制 elb
$ printf "%x\n" 3611
e1b
打开文件 jstack.3610
,找到线程号elb
运行代码栈
"main" prio=10 tid=0x00007fe504007800 nid=0xe1b runnable [0x00007fe50a1ef000]
java.lang.Thread.State: RUNNABLE
at HighCPUTest.main(HighCPUTest.java:3)
可以看到 HighCPUTest.java:3 可能存在问题,接下来就可以阅读代码分析了
Windows
jstack PID
输出代码运行栈信息,保存到文件中
$ jstack 361 > jstack.361
使用windows计算器[程序员] 将10进制线程号3816
转换为16进制 ee8
打开文件 jstack.361
,找到线程号ee8
运行代码栈
"main" #1 prio=5 os_prio=0 tid=0x02614400 nid=0xee8 runnable [0x00cdf000]
java.lang.Thread.State: RUNNABLE
at HighCPUTest.main(HighCPUTest.java:3)
可以看到 HighCPUTest.java:3 可能存在问题,接下来就可以阅读代码分析了
EOF