java 如何获取线程的堆栈跟踪
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3734696/
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
How to get stack trace of a thread
提问by Palo
I have a multithreaded application. Several messages are coming to the application and are processed in separated threads. For this I am using classes ThreadPoolExecutor and FutureTask from package java.util.concurrent.
我有一个多线程应用程序。有几条消息正在进入应用程序,并在单独的线程中进行处理。为此,我使用包 java.util.concurrent 中的类 ThreadPoolExecutor 和 FutureTask。
Occasionally I have some deadlocks in the application. When a deadlock occurs I want to interrupt the blocking thread and I want to log the stack trace of this thread so that I can later resolve the deadlock.
有时我在应用程序中遇到一些死锁。当发生死锁时,我想中断阻塞线程并记录该线程的堆栈跟踪,以便稍后解决死锁。
Is there any way how can we find the stack trace of a thread outside of that thread in Java?
有什么办法可以在Java中找到该线程之外的线程的堆栈跟踪?
回答by Brian Agnew
See herefor how to generate stack traces, including how to do this programatically. From the console, Ctrl+Breakwill dump the stack traces to stdout. See also this SO questionfor more details.
请参阅此处了解如何生成堆栈跟踪,包括如何以编程方式执行此操作。在控制台中,Ctrl+Break会将堆栈跟踪转储到标准输出。有关更多详细信息,另请参阅此 SO 问题。
回答by Thomas Mueller
You could log the stack traces of all thread from time to time (or before killing the process) from within your application. To do that use:
您可以不时(或在终止进程之前)从应用程序中记录所有线程的堆栈跟踪。要做到这一点,请使用:
Map<Thread, StackTraceElement[]> m = Thread.getAllStackTraces();
for(Map.Entry<Thread, StackTraceElement[]> e : m.entrySet()) {
log(e.getKey().toString());
for (StackTraceElement s : e.getValue()) {
log(" " + s);
}
}
When running nightly automated tests, sometimes some one of the test cases gets into a deadlock. I added a "TimeBomb" daemon thread that waits 30 minutes, and if then logs all stack traces as above.
在夜间运行自动化测试时,有时某些测试用例会陷入僵局。我添加了一个等待 30 分钟的“TimeBomb”守护进程线程,然后记录所有堆栈跟踪,如上。
回答by Peter Lawrey
Before entering the deadlock region, set a field like,
在进入死锁区域之前,设置一个字段,例如,
thread = Thread.currentThread();
In your monitoring thread you can perform thread.getStackTrace();to get the stack trace of that thread at any time.
在您的监控线程中,您可以执行thread.getStackTrace(); 随时获取该线程的堆栈跟踪。
回答by Faisal Feroz
You use JStack. Here is a nice blog entrythat details how to get stack traces.
您使用 JStack。这是一个很好的博客条目,详细介绍了如何获取堆栈跟踪。
回答by Toby
When a deadlock occurs I want to interrupt the blocking thread ...
当发生死锁时,我想中断阻塞线程......
You couldimplement a periodic task to check for deadlocks (where deadlocks are java intrinsic or Lock
based) and call interrupt
on all threads involved in the scenario. However, this has no guarantees that it will solve your problem. Its likely the scenario that will just happen again. See Dr Heinz's article on a deadlock detectorfor details.
您可以实施定期任务来检查死锁(死锁是 Java 内在的或Lock
基于Java的)并调用interrupt
场景中涉及的所有线程。但是,这并不能保证它会解决您的问题。它很可能会再次发生这种情况。有关详细信息,请参阅Heinz 博士关于死锁检测器的文章。
If fact, there is no guarantee that interrupt
will even free up a blocked process like this. Its a far better approach to avoid the deadlock scenario in the first place by, for example, using locks with timeouts and retry strategies or 'try before you buy' approaches.
事实上,不能保证interrupt
甚至会释放像这样被阻塞的进程。这是首先避免死锁场景的更好方法,例如,使用带有超时和重试策略的锁或“先试后买”的方法。
and I want to log the stack trace of this thread...
我想记录这个线程的堆栈跟踪......
If you want to do this programatically, again, follow Dr Heinz's example. If not, just generate the thread dump when you've spotted the problem.
如果您想以编程方式执行此操作,请再次按照 Heinz 博士的示例进行操作。如果没有,请在发现问题时生成线程转储。
Is there any way how can we find the stack trace of a thread outside of that thread in Java?
有什么办法可以在Java中找到该线程之外的线程的堆栈跟踪?
Yes and no. You can dump the threads from other VMs but their stack traces may not be as useful as you might think to determining the causes of your deadlock. If a genuine deadlock has been detected (by the JVM itself on thread dump of yourapplications VM) you should have everything you need to debug the cause (more or less).
是和否。您可以从其他 VM 转储线程,但它们的堆栈跟踪可能不像您认为的那样有用,可以确定死锁的原因。如果一个真正的僵局已经被检测到(由JVM本身的线程转储你的应用程序虚拟机),你应该有你需要调试的原因(或多或少)的一切。
回答by Vineet Reynolds
I wasn't sure if you wish to obtain the stacktrace from within the same JVM or externally, but if you wish to obtain the stack trace with external tools, the following will help:
我不确定您是否希望从同一 JVM 内或外部获取堆栈跟踪,但如果您希望使用外部工具获取堆栈跟踪,以下内容将有所帮助:
- The Java VisualVMtool can be used to connect to the running JVM, where the thread stack can be dumped. This is usually the preferred approach for most people using Java 6. Once VisualVM is launched, the thread dump of the process can be obtained by selecting the process in the Application tab. A Threads tab is now made available to view the threads in the running process, and in the same tab you'll find the "Thread Dump" button to extract the required information.
- The jstackutility within the JDK can also be used to produce thread stacktraces.
- Java VisualVM工具可用于连接到正在运行的 JVM,可以在其中转储线程堆栈。对于大多数使用 Java 6 的人来说,这通常是首选方法。启动 VisualVM 后,可以通过在“应用程序”选项卡中选择进程来获取进程的线程转储。线程选项卡现在可用于查看正在运行的进程中的线程,在同一选项卡中,您将找到“线程转储”按钮以提取所需的信息。
- JDK 中的jstack实用程序也可用于生成线程堆栈跟踪。