Java 在生产中定期进行线程转储是否昂贵?

Java 在生产中定期进行线程转储是否昂贵?,java,jvm,Java,Jvm,我们在生产中有一个Java应用程序,其中某个线程正在暂停/备份。线程正在读取队列,我们测量处理插入的任务所需的时间。调试根本原因的最佳方法是什么。每隔一分钟(通过脚本)执行peroidic线程转储会提供更多信息吗?其他人做了什么来调试这种情况 在我工作的系统中,我们监控任务执行所需的时间。如果这个时间超过了X个时间量,我们将触发一个线程转储(以编程方式,从我们测量时间的点开始,所以不是外部脚本),几秒钟后再触发另一个线程转储。这个阈值X应该是一个相对较大的数字,在我们的例子中是5分钟。如果发生这

我们在生产中有一个Java应用程序,其中某个线程正在暂停/备份。线程正在读取队列,我们测量处理插入的任务所需的时间。调试根本原因的最佳方法是什么。每隔一分钟(通过脚本)执行peroidic线程转储会提供更多信息吗?其他人做了什么来调试这种情况

在我工作的系统中,我们监控任务执行所需的时间。如果这个时间超过了X个时间量,我们将触发一个线程转储(以编程方式,从我们测量时间的点开始,所以不是外部脚本),几秒钟后再触发另一个线程转储。这个阈值X应该是一个相对较大的数字,在我们的例子中是5分钟。如果发生这种情况,我们可以假设系统不是“很慢”,而是发生了一些不好的事情,比如死锁或非常长的阻塞调用


因此,回答部分问题:是的,定期线程转储可能会有所帮助,但前提是转储发生在您要查找的事件发生的确切时刻。如果您只是每10秒生成一个线程转储,那么找到正确的转储可能会很痛苦。。。除非您正在寻找死锁,否则工具可以帮助您解决。我无法回答您问题的性能部分。

假设您的线程正在从一个简单的并发队列实现中提取任务,我将首先检查垃圾收集是否是罪魁祸首。如果尚未这样做,则需要添加命令行选项以打开GC日志记录:

-XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCDateStamps -Xloggc:<some-file>
-XX:+PrintGCApplicationStoppedTime-XX:+PrintGCApplicationConcurrentTime-XX:+PrintGCDateStamps-Xloggc:

如果你确信这不是垃圾回收,那么你可以考虑使用一些类似于监视摊位的东西,特别是如果你的应用程序是在虚拟化环境中运行的。

< P>在生产中周期性的线程转储肯定是一个昂贵的操作。因为您给了JVM额外的任务来打印JVM生成的所有线程的所有当前执行堆栈

如果您有权访问代码,我建议您使用其他日志来打印性能日志和计时数据

如果您无法访问代码,我建议您使用APM工具,如dynatrace、appdynamics或任何可用于调试耗时方法或第三方调用的工具

希望这有帮助

问候,,
Eby J

好吧,如果你的线程一开始工作不正常,那么性能可能不是你最关心的问题。问题只发生在生产中吗?您是否在临时服务器上进行了集成测试?它在生产中只进行过一次。QA中从未出现过问题-可能是因为我们没有太多的流程。我关心的是在生产环境中默认启用此功能。您是在谈论从标准阻止队列或更复杂的JMS队列中提取任务吗?感谢您提供有关以编程方式获取转储的提示。