无法获取线程转储?任何想法为啥我的应用程序阻塞?

Posted

技术标签:

【中文标题】无法获取线程转储?任何想法为啥我的应用程序阻塞?【英文标题】:Unable to get thread dump? Any ideas why my app blocks?无法获取线程转储?任何想法为什么我的应用程序阻塞? 【发布时间】:2011-04-08 12:44:38 【问题描述】:

我有一个基本的 java 服务器应用程序,它有 100 个工作线程,它们在 url 上执行简单的 HEAD 请求。我为此使用 HttpClient 4.x。

运行几分钟后,我的程序就冻结了几分钟,我不知道为什么。查看视觉 vm 监视器报告的屏幕截图。你可以看到它是平的。在此期间,我无法获得良好的线程转储,并且视觉虚拟机只是冻结,直到它被解除阻塞。有没有人知道我可以做些什么来尝试开始调试这个家伙?

视觉虚拟机:http://tinypic.com/view.php?pic=2i915bs&s=7

这是我在冻结时尝试获取 jstack 转储时的输出:

jstack -F 4325 
Attaching to process ID 4325, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 16.3-b01
Deadlock Detection:

No deadlocks found.

Thread 4557: (state = BLOCKED)
Error occurred during stack walking:
sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.debugger.DebuggerException: get_thread_regs failed for a lwp
    at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$LinuxDebuggerLocalWorkerThread.execute(LinuxDebuggerLocal.java:152)
    at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.getThreadIntegerRegisterSet(LinuxDebuggerLocal.java:466)
    at sun.jvm.hotspot.debugger.linux.LinuxThread.getContext(LinuxThread.java:65)
    at sun.jvm.hotspot.runtime.linux_amd64.LinuxAMD64JavaThreadPDAccess.getCurrentFrameGuess(LinuxAMD64JavaThreadPDAccess.java:92)
    at sun.jvm.hotspot.runtime.JavaThread.getCurrentFrameGuess(JavaThread.java:256)
    at sun.jvm.hotspot.runtime.JavaThread.getLastJavaVFrameDbg(JavaThread.java:218)
    at sun.jvm.hotspot.tools.StackTrace.run(StackTrace.java:76)
    at sun.jvm.hotspot.tools.StackTrace.run(StackTrace.java:45)
    at sun.jvm.hotspot.tools.JStack.run(JStack.java:60)
    at sun.jvm.hotspot.tools.Tool.start(Tool.java:221)
    at sun.jvm.hotspot.tools.JStack.main(JStack.java:86)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at sun.tools.jstack.JStack.runJStackTool(JStack.java:118)
    at sun.tools.jstack.JStack.main(JStack.java:84)
Caused by: sun.jvm.hotspot.debugger.DebuggerException: get_thread_regs failed for a lwp
    at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.getThreadIntegerRegisterSet0(Native Method)
    at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.access$800(LinuxDebuggerLocal.java:51)
    at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$1GetThreadIntegerRegisterSetTask.doit(LinuxDebuggerLocal.java:460)
    at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$LinuxDebuggerLocalWorkerThread.run(LinuxDebuggerLocal.java:127)

【问题讨论】:

我也有这个问题,似乎(不能保证)它主要发生在 64 位 jvm 上。 请求都发往同一台服务器吗? (即你确定不是服务器不响应请求吗?) 【参考方案1】:

我在 Linux 上看到了几个关于 jstack 的错误报告,并带有类似的跟踪:

JVM Bug Id: 6494722(应该是固定的) Ubuntu Bug #597098(这个不是)

kill -3 <pid> 得到相同的结果吗?

【讨论】:

【参考方案2】:

非常可能由于内存使用过多导致 GC。将参数添加到 java:

-verbosegc -XX:+PrintGCDetails

看看你是否注意到输出/日志中有任何明显的东西

【讨论】:

【参考方案3】:

对我有用的是运行 jstack 作为进程所有者没有 -F

【讨论】:

以上是关于无法获取线程转储?任何想法为啥我的应用程序阻塞?的主要内容,如果未能解决你的问题,请参考以下文章

阻塞 HeapTaskDaemon 线程的 ANR

为啥我的异步 ASP.NET Web API 控制器阻塞了主线程?

为啥我的 IUnknown 释放函数会阻塞我的子线程?

为啥我的 MFC 应用程序无法完全退出?

分析线程转储 - sun.misc.Unsafe.park 上的许多阻塞线程 [重复]

为啥 File.ReadAllLinesAsync() 会阻塞 UI 线程?