使用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

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