【问题标题】:How to figure out why thread is stuck?如何找出线程卡住的原因?
【发布时间】:2014-09-02 15:42:39
【问题描述】:

我在我的 jstack 中看到这个线程似乎根本没有移动。关于如何弄清楚为什么卡住的任何指示?我没有看到任何锁或任何东西,唯一可疑的是“Object.wait()”引用。

"main" prio=10 tid=0x00007f3a8000b000 nid=0x942 in Object.wait() [0x00007f3a89539000]
   java.lang.Thread.State: RUNNABLE
        at org.joda.time.DateTimeZone.<clinit>(DateTimeZone.java:95)
        at org.joda.time.format.DateTimeFormatter.withZoneUTC(DateTimeFormatter.java:301)
        at com.amazonaws.auth.AWS4Signer.<clinit>(AWS4Signer.java:44)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
        at java.lang.Class.newInstance0(Class.java:372)
        at java.lang.Class.newInstance(Class.java:325)
        at com.amazonaws.auth.SignerFactory.createSigner(SignerFactory.java:121)
        at com.amazonaws.auth.SignerFactory.lookupAndCreateSigner(SignerFactory.java:107)
        at com.amazonaws.auth.SignerFactory.getSigner(SignerFactory.java:80)
        at com.amazonaws.AmazonWebServiceClient.computeSignerByServiceRegion(AmazonWebServiceClient.java:311)
        at com.amazonaws.AmazonWebServiceClient.computeSignerByURI(AmazonWebServiceClient.java:284)
        at com.amazonaws.AmazonWebServiceClient.setEndpoint(AmazonWebServiceClient.java:160)

另外,堆栈顶部的 DateTimeZone.java 中的第 95 行是这样的:

   public static final DateTimeZone UTC = new FixedDateTimeZone("UTC", "UTC", 0, 0);

还有另一个线程也卡在了类似的地方:

"FeatureManagerService" daemon prio=10 tid=0x00007f3a8056a800 nid=0x94f in Object.wait() [0x00007f3a84151000]
   java.lang.Thread.State: RUNNABLE
        at com.amazonaws.util.DateUtils.<clinit>(DateUtils.java:35)
        at com.amazonaws.services.s3.internal.ServiceUtils.<clinit>(ServiceUtils.java:59)
        at com.amazonaws.services.s3.internal.S3Signer.sign(S3Signer.java:123)
        at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:348)
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:245)
        at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3711)
        at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3664)
        at com.amazonaws.services.s3.AmazonS3Client.listObjects(AmazonS3Client.java:620)
        at com.amazonaws.services.s3.AmazonS3Client.listObjects(AmazonS3Client.java:603)

而 DateUtils.java:35 是:

private static final DateTimeZone GMT = new FixedDateTimeZone("GMT", "GMT", 0, 0);

我已经尝试使用 jvisualvm/jhat 对其进行研究,但并没有真正深入。

请注意,这是一个实时进程,而不是我在本地调试器中运行的进程,重新启动后它工作正常,因此它似乎是间歇性的。

任何帮助将不胜感激!

谢谢!

更新在 jstack 中使用混合模式似乎可以提供更多见解 - 它正在等待 pthread_cond_wait:

----------------- 2370 -----------------
0x00007f3a89115414      __pthread_cond_wait + 0xc4
0x00007f3a8833a03c      _ZN13ObjectMonitor4waitElbP6Thread + 0x7dc
0x00007f3a88117fbb      _ZN13instanceKlass15initialize_implE19instanceKlassHandleP6Thread + 0x36b
0x00007f3a881182ca      _ZN13instanceKlass10initializeEP6Thread + 0x6a
0x00007f3a8814d3f3      _ZN18InterpreterRuntime4_newEP10JavaThreadP19constantPoolOopDesci + 0x143
0x00007f3a7d01d9ee      * org.joda.time.DateTimeZone.<clinit>() bci:0 line:95 (Interpreted frame)
0x00007f3a7d0004f7      <StubRoutines>
...

【问题讨论】:

  • 还有其他线程在做什么吗?有线程转储吗?
  • 还有一些其他线程 - 我应该寻找什么?
  • @ssnobody 在创建 FixedDateTimeZone 之前发现另一个线程卡住了
  • 我相信 java 中的大多数挂起是由于无限循环或等待锁。研究将获得这些锁的同步方法或块将是我的第一步,但简单地获得这些锁的列表也可能很有用。该列表应在线程转储/javacore 的 LK 子组件转储例程中找到。此外,javadump(生成线程转储的工具)有时可以直接诊断死锁本身。
  • 很高兴你知道了!

标签: java debugging jodatime stack-trace jstack


【解决方案1】:

也许它没有被卡住。它只是在循环中调用 new DateTimeZone() ,并且构造函数会进行一些计算。每次查看此线程时,它都在 DateTimeZone() 内 - 但每次都是不同的 DateTimeZone()。

然后被丢弃。发生在我身上好几次了。

【讨论】:

  • 你是完全正确的,有时会发生这种情况,但你通常可以通过变量的地址来判断,在这种情况下,地址保持不变,这让我认为这不是一个循环。好主意。
【解决方案2】:

@naumcho 发现,这被证明是一个错误 (https://github.com/JodaOrg/joda-time/issues/171)。

根据提供的信息(两个不同线程的堆栈跟踪 + 源代码行),人们可能怀疑死锁,因为两个线程都在尝试实例化同一类型的新对象 FixedDateTimeZone

确认这一点的下一步是使用 GDB 检查 __pthread_cond_wait() 周围的堆栈帧。

【讨论】:

    猜你喜欢
    • 2019-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    相关资源
    最近更新 更多