java程序线上运行时,出现cpu过高的情况如何进行定位呢?
记得刚参加工作的时候,老同事留下的一个项目,出现了cpu100%的情况,后来检查代码发现,之前的同事在写这块的时候,没有考录到多线程并发的问题,有个定时器偶发的多线程情况下同时写入同一个hashmap,导致cpu爆表
我们写一个小demo进行演示
首先准备一段java示例代码:
public class Test{
public static void main(String args[]){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while (true){
System.out.println(i++);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread.setName("mytest");
thread.start();
}
新启了一个线程,每10毫秒输出自增的数,在1c1g的机器上已经能体现出来消耗了
准备好Test.java文件,
使用javac Test.java命令编译java代码;
使用nohup java Test &启动java进程;

使用tail -f nohup.out已经能看到程序的输出了

我们可以去定位这个耗费资源比较大的线程了;
首先使用top -H命令

持续观察可以看到3624这个线程一直处在占用cpu的状态,这里时间间隔10ms负载并不大,所以占用的不多,不过已经可以展示了
使用jps命令查看当前系统中运行的java进程

使用printf %x 3624 获取3624这个线程的16进制数,因为java的线程id都是使用十六进制数表示的

获得了e28这个id
下来使用jstack 3614打印jvm的堆栈信息

由于程序比较简单,打印出来的内容就这么多,我们在堆栈信息中找到e28这个线程对应的信息,

可以看到,这个线程整处于sleep状态,
这样我们就能找对问题的地方,去排查问题了
本文通过一个简单的Java示例,演示了如何定位导致CPU过高的线程。从代码问题出发,利用top、jps和jstack等工具,逐步定位到具体线程,为解决Java程序中的性能瓶颈提供了一种有效的方法。
911

被折叠的 条评论
为什么被折叠?



