当前位置: 首页 > 面试题库 >

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

闻人博
2023-03-14
问题内容

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

当前调试说明:

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 18975 说没有死锁, jstack -m 18975 不起作用

3) jstack -l 18975 确实给了我所有线程的堆栈跟踪信息( 〜400 )。示例线程堆栈( 不是问题 ):

“ http-342.877.573.944-8080-360”守护程序prio = 10 tid = 0x0000002adaba9c00 nid = 0x754c in Object.wait()[0x00000000595bc000..0x00000000595bccb0]
   java.lang.Thread.State:等待(在对象监视器上)
        在java.lang.Object.wait(本地方法)
        -等待(org.apache.tomcat.util.net.JIoEndpoint $ Worker)
        在java.lang.Object.wait(Object.java:485)
        在org.apache.tomcat.util.net.JIoEndpoint $ Worker.await(JIoEndpoint.java:416)
        -锁定(org.apache.tomcat.util.net.JIoEndpoint $ Worker)
        在org.apache.tomcat.util.net.JIoEndpoint $ Worker.run(JIoEndpoint.java:442)
        在java.lang.Thread.run(Thread.java:619)

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

5)没有繁重的IO,内存使用或其他相应的活动线索可以使用。

平台:

  • Java 6
  • Male cat 6
  • RHEL 4(64位)

有谁知道我怎样才能从Linux ps输出到问题子Java线程建立连接?如此接近,却至今……


问题答案:

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

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

将nid转换为十进制,您将获得LWP
ID。在您的情况下,0x754c是30028。此过程未在我们的ps输出中显示,但它可能是您为了节省空间而省略的LWP之一。

这是一个Perl片段,可用于将jstack的输出传递给:

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


 类似资料:
  • 问题内容: 我有一个Java应用程序,其中创建了一些线程(通过)。通过使用,我可以看到它们具有不同的线程ID(LWP列),我想从Java应用程序中获取这些ID。 在我发现的与此主题相关的大多数文章中,解决方案是使用。 但是,使用该方法可以为我提供主线程的PID(即使我从其中一个线程调用它),因此它并不能真正解决我的问题。 有什么方法可以获取应用程序创建的每个线程的线程ID ? 是否可以使用JNI完

  • 问题内容: 我想知道是否有人可以指出有关解释用提取的Java线程堆栈的信息。 我的情况是我在GlassFish v2.1.1上运行了一个Java EE 5应用程序,该应用程序定期挂起(每天至少挂2次-3次)。要使其再次运行,我必须终止Glassfish进程并重新启动域。 。应用程序通常会变得越来越慢,直到最终完全挂起。一旦挂起,我将无法获得线程堆栈。我已经能够获得一个线程堆栈,因为它变得越来越慢,

  • 当我研究线程及其占用的内存(线程堆栈)时,我决定做一个简单的负载测试,看看线程的数量如何影响我的计算机上的RAM。 所以,在测试中,我使用了Tomcat,在设置中。xml将最小和最大web容器线程池设置为200。在那之后,我在将pool设置为2000时也做了同样的操作。我很震惊,因为内存占用没有差异(通过Windows任务管理器进行检查),而且几乎是一样的。所以我认为这些线程可能必须处于运行状态,

  • 本文向大家介绍深入JVM剖析Java的线程堆栈,包括了深入JVM剖析Java的线程堆栈的使用技巧和注意事项,需要的朋友参考一下 在这篇文章里我将教会你如何分析JVM的线程堆栈以及如何从堆栈信息中找出问题的根因。在我看来线程堆栈分析技术是Java EE产品支持工程师所必须掌握的一门技术。在线程堆栈中存储的信息,通常远超出你的想象,我们可以在工作中善加利用这些信息。 我的目标是分享我过去十几年来在线程

  • 问题内容: 我正在尝试转储所有活动线程的列表,包括每个线程的当前堆栈。我可以使用threading.enumerate()获得所有线程的列表,但是我不知道从那里到堆栈的方法。 背景:Zope / Plone应用程序有时会出现故障,消耗100%的cpu,需要重新启动。我觉得这是一个循环,无法正常终止,但是我无法在test- environemt中重现该循环以进行验证。我设法注册了可以从外部触发的信号