Java程序模拟cpu飙升问题排查

1. 模拟

不断的运算,会造成cpu使用率的飙升。所以我们需要在Java程序中做运算,一个线程有可能飚不到很高,所以我们启动了10个线程。

@RequestMapping("/main")
public class MainController {

    private static volatile  boolean exit= true;

    @RequestMapping("/start")
    public void start() {
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i =0;i<10;i++){
            executorService.submit(() -> {
                int k = 0;
                while (MainController.exit){
                    k++;
                }
            });
        }
    }
    @RequestMapping("/stop")
    public void stop() {
        exit = false;
    }
}
2. 部署服务器

部署到服务器上,启动工程

3. 访问服务
http://192.168.52.200:8881/main/start
3.1 TOP查看

直接看到第一行,CPU的使用率已经达到了99%,接下来我们开始排查具体是什么导致的。假设我们现在对项目具体代码不清楚。
在这里插入图片描述

3.2 拿到线程ID

这里我们从图上可以直接看到,PID = 32008

3.3 根据进程找到该进程下线程的CPU使用情况
ps -mp 32008 -o THREAD,tid,time | sort -rn

或者

top -H -p 32008

结果,我们以第一种为例,可以看到占用CPU高的线程全部打印了出来。到此,我们先以tid为32043为例子。
在这里插入图片描述

3.4 将TID转换为16进制

因为在线程信息中,我们要找到这个线程,他都是一16进制表示ID的,所以我们先转化一下。

printf "%x\n" tid

结果
在这里插入图片描述

3.5 根据线程ID查找信息
jstack pid |grep 7d2b -A 30

结果,我们可以看到这个方法的调用栈了,至此我们应该知道到底是哪里出了问题。

"pool-1-thread-10" #36 prio=5 os_prio=0 tid=0x00007f9c30005800 nid=0x7d2b runnable [0x00007f9c256d0000]
   java.lang.Thread.State: RUNNABLE
	at com.example.yunwei.MainController.lambda$start$0(MainController.java:25)
	at com.example.yunwei.MainController$$Lambda$460/835609887.run(Unknown Source)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

"pool-1-thread-9" #35 prio=5 os_prio=0 tid=0x00007f9c30004000 nid=0x7d2a runnable [0x00007f9c257d1000]
   java.lang.Thread.State: RUNNABLE
	at com.example.yunwei.MainController.lambda$start$0(MainController.java:25)
	at com.example.yunwei.MainController$$Lambda$460/835609887.run(Unknown Source)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

"pool-1-thread-8" #34 prio=5 os_prio=0 tid=0x00007f9c30002800 nid=0x7d29 runnable [0x00007f9c258d2000]
   java.lang.Thread.State: RUNNABLE
	at com.example.yunwei.MainController.lambda$start$0(MainController.java:25)
	at com.example.yunwei.MainController$$Lambda$460/835609887.run(Unknown Source)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

"pool-1-thread-7" #33 prio=5 os_prio=0 tid=0x00007f9c300d0000 nid=0x7d28 runnable [0x00007f9c259d3000]

4 总结
  1. Top命令查找PID
  2. 根据PID查找对应的TID
  3. 将TID转化为16进制方便查看
  4. 根据jstack命令查看该TID的调用栈信息。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值