2016-01-07 18 views
3

在分析性能问题时,我每5秒持续线程转储,并使用武士线程转储分析器进行分析。注意到,许多线程处于可运行状态,并且在所有事件中持续存在堆栈转储。但我找不到他们正在通信的主机。我尝试使用命令ss -t -a,watch ss -tpnetstat -A inet -p,但无法将其结果与线程相关联。任何想法?提前致谢。来自Linux-Java线程转储的套接字信息

Thread dump 2/5 "TP-Processor125" prio=5 tid=0x25756 nid=0x649c RUNNABLE (JNI Native Code) - stats: cpu=828 blk=-1 wait=-1      java.lang.Thread.State: RUNNABLE      
    at java.net.SocketInputStream.socketRead0(Native Method)      
    at java.net.SocketInputStream.read(SocketInputStream.java:152)      
    at java.net.SocketInputStream.read(SocketInputStream.java:122)      
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)      
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:275)      
    at java.io.BufferedInputStream.read(BufferedInputStream.java:334)      
    at org.apache.jk.common.ChannelSocket.read(ChannelSocket.java:628) 
     at org.apache.jk.common.ChannelSocket.receive(ChannelSocket.java:566) 
     at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:693) 
     at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:898) 
     at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690) 
     at java.lang.Thread.run(Thread.java:745)      Locked synchronizers: count = 0 
+0

这是服务器还是客户端?例如。服务器套接字或客户端套接字? – MojoJojo

+0

对不起,我没有这个信息。我所拥有的只是从服务器获取的线程转储。它与许多接口交互,包括数据库,Web服务器等等。它说'SocketInputStream.read'。它可以是服务器套接字吗? –

+0

转储有多大?你可能会上传到Github或其他份额? – MojoJojo

回答

2

nid实际上是底层OS(至少对于Linux)的进程/线程ID,尽管在十六进制表示法。转换为十进制pid并使用

lsof -p pid |grep -Ei 'tcp|socket' 

了解更多关于使用的套接字连接。不过,可能会发现,所有套接字都是由主线程打开的,在这种情况下,子线程只会继承几个(很多)线程,因此可能难以查看哪个线程连接了哪个线程。

如果lsof没有显示主进程的线程(看起来确实没有),您可能需要解析以查看/proc/<pid>/fd

+0

做到了这一点,但没有得到结果。不确定lsof只接受进程标识而不是线程标识。此外,当我将十六进制转换为十进制,并发出'ps -eLf | grep 25781'来获取线程的细节,但没有得到任何结果。这里25781是十六进制nid(0x64b5)的十进制值。 –

1

tid是Java级别线程标识,nid是本地线程标识。 nid实际上指的是不同操作系统,是somewhat confusing。我建议使用VisualVM等工具连接到您的应用程序,并注意应用程序的PID。一旦你的PID,请尝试以下命令:

sudo netstat -nlpt 

这应该给你的东西像下面(远程/本地地址和PID和节目名称):

Active Internet connections (only servers) 
Proto Recv-Q Send-Q Local Address   Foreign Address   State  PID/Program name 
tcp  0  0 127.0.1.1:53   0.0.0.0:*    LISTEN  1144/dnsmasq  
tcp  0  0 127.0.0.1:631   0.0.0.0:*    LISTEN  661/cupsd  
tcp6  0  0 ::1:631     :::*     LISTEN  661/cupsd 

这应该告诉你哪些连接从您的Java程序打开。

+0

谢谢MajoJojo。但是这种方法再次在pid层面进行会谈。我想知道的是在线程级别。 Pid有很多线程,线程转储显示每个线程正在做什么。在unix中,ps -eLf命令会列出线程和进程。如果我们知道进程ID,我们可以运行'ps -eLf | grep pid'来知道线程列表。在我的线程转储中,许多线程正在从套接字读取数据,但我无法识别那个套接字是什么。希望我清楚我的问题。 –