使用arthas定位耗时CPU的线程

在分析CPU占用率很高的线程以及问题定位时,一般都是使用top和jstack命令,但是整个过程比较慢,确实使用arthas就可以非常快速地定位到耗时最快的线程

使用arthas

https://arthas.aliyun.com/doc/quick-start.html

curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar

定位CPU占用率最高的线程

  • 按照CPU使用率排序,并展示前n个线程
thread -n {number}
[arthas@1]$ thread -n 1
"arthas-command-execute" Id=8286 cpuUsage=0.4% deltaTime=0ms time=22ms RUNNABLE
    at sun.management.ThreadImpl.dumpThreads0(Native Method)
    at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:448)
    at com.taobao.arthas.core.command.monitor200.ThreadCommand.processTopBusyThreads(ThreadCommand.java:206)
    at com.taobao.arthas.core.command.monitor200.ThreadCommand.process(ThreadCommand.java:122)
    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:82)
    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:18)
    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:111)
    at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:108)
    at com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:385)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
  • 展示指定线程的线程栈
thread [pid]
[arthas@1]$ thread 3422
"grpc-default-executor-2" Id=3422 TIMED_WAITING on java.util.concurrent.SynchronousQueue$TransferStack@56b72395
    at sun.misc.Unsafe.park(Native Method)
    -  waiting on java.util.concurrent.SynchronousQueue$TransferStack@56b72395
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
    at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
    at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1073)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

为什么有时候CPU使用率排第一的线程状态是WAITING?

在定位问题的时候,发现CPU使用率最高的线程的状态是WAITING,一个在等待的线程怎么可能占用CPU呢? 实际上这是因为CPU使用率的计算是通过采样的方式得到的,并不是当前时刻的CPU使用率,所以原因是在进入WAITING之前,占用了很多的CPU

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章