获取 Java 线程 ID 和失控 Java 线程的堆栈跟踪

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/222108/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 11:38:52  来源:igfitidea点击:

Getting the Java thread id and stack trace of run-away Java thread

javadebuggingjstack

提问by Stu Thompson

On my busiest production installation, on occasion I get a single thread that seems to get stuck in an infinite loop. I've not managed to figure out who is the culprit, after much research and debugging, but it seems like it should be possible. Here are the gory details:

在我最繁忙的生产安装中,有时我会遇到一个似乎陷入无限循环的线程。经过大量研究和调试,我还没有弄清楚谁是罪魁祸首,但似乎应该是可能的。以下是血腥细节:

Current debugging notes:

当前调试说明:

1) ps -eL 18975shows me the the Linux pid the problem child thread, 19269

1) ps -eL 18975向我展示了问题子线程的 Linux pid,19269

$ps -eL | grep 18975
...
PID   LWP   TTY          TIME CMD
18975 18994 ?        00:00:05 java
18975 19268 ?        00:00:00 java
18975 19269 ?        05:16:49 java
18975 19271 ?        00:01:22 java
18975 19273 ?        00:00:00 java
...

2) jstack -l 18975says there are no deadlocks, jstack -m 18975does not work

2) jstack -l 18975表示没有死锁,jstack -m 18975不起作用

3) jstack -l 18975does give me the stack trace for all my threads (~400). Example thread stack (and not the problem):

3) jstack -l 18975确实为我提供了所有线程的堆栈跟踪 (~400)。示例线程堆栈(而不是问题):

"http-342.877.573.944-8080-360" daemon prio=10 tid=0x0000002adaba9c00 nid=0x754c in Object.wait() [0x00000000595bc000..0x00000000595bccb0]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on  (a org.apache.tomcat.util.net.JIoEndpoint$Worker)
        at java.lang.Object.wait(Object.java:485)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:416)
        - locked  (a org.apache.tomcat.util.net.JIoEndpoint$Worker)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:442)
        at java.lang.Thread.run(Thread.java:619)

4) The ps -eL output's thread ID does not match the output from jstack, or at least I cannot see it. (jstack documentation is a bit sparse.)

4) ps -eL 输出的线程 ID 与 jstack 的输出不匹配,或者至少我看不到它。(jstack 文档有点稀疏。)

5) There are no heavy IO, memory usage or other corresponding activity clues to work with.

5) 没有大量的 IO、内存使用或其他相应的活动线索可供使用。

Platform:

平台:

  • Java 6
  • Tomcat 6
  • RHEL 4 (64-bit)
  • 爪哇 6
  • 雄猫6
  • RHEL 4(64 位)

Does anybody know how I can make that connection from the linux ps output to my problem child java thread? So close, yet so far...

有谁知道我如何从 linux ps 输出到我的问题子 java 线程建立连接?这么近,又这么远……

采纳答案by ubiyubix

It looks like the nidin the jstack output is the Linux LWP id.

看起来jstack 输出中的nid是 Linux LWP id。

"http-342.877.573.944-8080-360" daemon prio=10 tid=0x0000002adaba9c00 nid=0x754c in Object.wait() [0x00000000595bc000..0x00000000595bccb0]

Convert the nid to decimal and you have the LWP id. In your case 0x754c is 30028. This process is not shown in our ps output, but it was probably one of the LWPs you have omitted to save space.

将 nid 转换为十进制,您就拥有了 LWP id。在你的例子中 0x754c 是 30028。这个过程没有显示在我们的 ps 输出中,但它可能是你为了节省空间而省略的 LWP 之一。

Here's a little a Perl snippet you can use to pipe the output of jstack to:

这里有一些 Perl 片段,您可以使用它来将 jstack 的输出通过管道传输到:

#!/usr/bin/perl -w
while (<>) {
    if (/nid=(0x[[:xdigit:]]+)/) {
        $lwp = hex();
        s/nid=/lwp=$lwp nid=/;
    }
    print;
}

回答by Steve K

You can use JConsoleto view the thread's stack trace.

您可以使用JConsole查看线程的堆栈跟踪。

If your using JDK 1.6.0_07 or above, you can also use visualvm.

如果您使用 JDK 1.6.0_07 或更高版本,您也可以使用visualvm

Both tools provide a nice view of all the running threads in an application. The visualvm is quite a bit nicer, but hopefully seeing all the threads can help you track down the run-away thread.

这两种工具都提供了应用程序中所有正在运行的线程的良好视图。visualvm 更好一些,但希望看到所有线程可以帮助您追踪失控的线程。

Check for threads that are alwaysin a state of RUNNING. When we had a run-away thread, the stack trace would constantly change. So we were able to tell which methods the loop was calling, and track down the loop.

检查始终处于 RUNNING 状态的线程。当我们有一个失控的线程时,堆栈跟踪会不断变化。所以我们能够知道循环调用了哪些方法,并跟踪循环。

回答by Aidos

From memory if you CTRL-BREAK on the console you will get a dump of the current threads and a few of their stack trace frames.

从内存中,如果您在控制台上按 CTRL-BREAK,您将获得当前线程的转储及其一些堆栈跟踪帧。

From memory (I'm not sure if this is an IntelliJ IDEa feature, or it is default in java) but it will tell you which thread is deadlocked, and which object they are waiting on. You should be able to redirect the output to a file, and just grep for the DEADLOCKED text.

从内存中(我不确定这是 IntelliJ IDEa 功能,还是 Java 中的默认功能),但它会告诉您哪个线程已死锁,以及它们正在等待哪个对象。您应该能够将输出重定向到一个文件,并且只对 DEADLOCKED 文本进行 grep。

JConsole, VisualVM or other profilers such as JProfiler will also show you the threads and their stacks, however if you don't want to use any external tool I think CTRL-BREAK will give you what you're looking for.

JConsole、VisualVM 或其他分析器(例如 JProfiler)也会向您显示线程及其堆栈,但是如果您不想使用任何外部工具,我认为 CTRL-BREAK 将为您提供所需的东西。

回答by yes

On SUN

在太阳

Note that prstatby default shows the no of light weight processes , not the LWPID.

请注意,prstat默认情况下显示的是轻量级进程数,而不是 LWPID。

To see information for all the lightweight processes for a particular user use the -Loption.

要查看特定用户的所有轻量级进程的信息,请使用该-L选项。

prstat -L -v -u weblogic

now use the LWPID and convert it into hex and match it with the nid from the thread dump

现在使用 LWPID 并将其转换为十六进制并将其与线程转储中的 nid 匹配

回答by aladin

Nice,useful answers!

不错,有用的答案!

For Linux, use ps -efL, -L option will show the LWPs. As a side note, the
"http-342.877.573.944-8080-360" daemon prio=10means "ThreadName(as given by the JVM)" runningmode(inherited from the pid) priority(inherited from the pid)

对于 Linux,使用 ps -efL,-L 选项将显示 LWP。作为旁注,
“http-342.877.573.944-8080-360”守护进程 prio=10表示“ ThreadName(由 JVM 给出)”运行模式(继承自 pid)优先级(继承自 pid)