jstack,arthas和linux线程id的关系

/ 默认分类 / 0 条评论 / 74浏览

jstack中的线程信息,下面是jstack输出的线程调用堆栈的信息示例:

"OkHttp ConnectionPool" #98 daemon prio=5 os_prio=0 tid=0x00007ffa9c118000 nid=0x65 in Object.wait() [0x00007ff9fcb43000]
    java.lang.Thread.State: TIMED_WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:460)
    at hidden.okhttp3.ConnectionPool$1.run(ConnectionPool.java:67)
    - locked <0x00000000810083a0> (a hidden.okhttp3.ConnectionPool)
    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)

alibaba开源的运维工具Arthas也可以查看线程信息,比如:thread -n 3就是查看当前cpu使用最频繁的前三个线程.显示的数据如下:

[arthas@1]$ thread -n 1
"XNIO-2 task-449" Id=842 cpuUsage=2.54% deltaTime=5ms time=484848ms WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@21b0a546
    at sun.misc.Unsafe.park(Native Method)
    -  waiting on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@21b0a546
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
    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)

这里显示的id是jstack中的java线程顺序编号,如上面的#98,也就是说这个 ID 不是jstack 中的 nativeID 。

我们可以基于这里的线程顺序编号,然后从jstack中的输出搜索这个编号或者搜索这个线程名,然后找到这个线程的nid,将16进制的nid转为10进制,然后这个十进制的线程nid就是linux系统中的线程十进制id了.

使用linux上的一些操作就可以跟踪到这个线程的相关信息了.

ls /proc/<pid>/task/
cat /proc/<pid>/task/<tid>/stat
cat /proc/<pid>/task/<tid>/status

arthas参考手册: Arthas