简体   繁体   English

在生产中进行线程转储

[英]Taking thread dumps in production

I am analyzing the differences between approaches for taking thread dumps. 我正在分析获取线程转储的方法之间的差异。 Below are the couple of them I am researching on 以下是我正在研究的几个人

  1. Defining a jmx bean which triggers jstack through Runtime.exec() on clicking a declared bean operation. 定义一个jmx bean,它在单击声明的bean操作时通过Runtime.exec()触发jstack。

  2. Daemon thread executing "ManagementFactory.getThreadMXBean().dumpAllThreads(true, true)" repeatedly after a predefined interval. 守护程序线程在预定义的时间间隔后重复执行“ManagementFactory.getThreadMXBean()。dumpAllThreads(true,true)”。

Comparing the thread dump outputs between the two, I see the below disadvantages with approach 2 比较两者之间的线程转储输出,我在方法2中看到了以下缺点

  1. Thread dumps logged with approach 2 cannot be parsed by open source thread dump analyzers like TDA 使用方法2记录的线程转储无法由TDA等开源线程转储分析器解析
  2. The ouput does not include the native thread id which could be useful in analyzing high cpu issues (right?) 输出不包括本机线程ID,它可用于分析高CPU问题(对吗?)
  3. Any more? 还有吗?

I would appreciate to get suggestions/inputs on 我很感激获得建议/意见

  1. Are there any disadvantages of executing jstack through Runtime.exec() in production code? 在生产代码中通过Runtime.exec()执行jstack是否有任何缺点? any compatibility issues on various operating systems - windows, linux? 各种操作系统上的兼容性问题 - windows,linux?

  2. Any other approach to take thread dumps? 采取线程转储的任何其他方法?

Thank you. 谢谢。

Edit - 编辑 -

A combined approach of 1 and 2 seems to be the way to go. 1和2的组合方法似乎是要走的路。 We can have a dedicated thread running in background and printing the thread dumps in the log file in a format understood by the thread dump analyzers. 我们可以在后台运行专用线程,并以线程转储分析器可以理解的格式在日志文件中打印线程转储。 If any extra information is need (like say probably the native thread id) which is logged only by the jstack output, we do it manually as required. 如果需要任何额外的信息(比如说可能是本机线程id)只能由jstack输出记录,我们会根据需要手动执行。

You can use 您可以使用

jstack {pid} > stack-trace.log

running as the user on the box where the process is running. 在进程运行的框上以用户身份运行。

If you run this multiple times you can use a diff to see which threads are active more easily. 如果多次运行,可以使用diff来更轻松地查看哪些线程处于活动状态。


For analysing the stack traces I use the following sampled periodically in a dedicated thread. 为了分析堆栈跟踪,我在专用线程中定期使用以下采样。

 Map<Thread, StackTraceElement[]> allStackTraces = Thread.getAllStackTraces();

Using this information you can obtain the thread's id, run state and compare the stack traces. 使用此信息,您可以获取线程的id,运行状态并比较堆栈跟踪。

With Java 8 in picture, jcmd is the preferred approach. 使用Java 8,jcmd是首选方法。

jcmd <PID> Thread.print

Following is the snippet from Oracle documentation : 以下是Oracle文档的片段:

The release of JDK 8 introduced Java Mission Control, Java Flight Recorder, and jcmd utility for diagnosing problems with JVM and Java applications. JDK 8的发布引入了Java Mission Control,Java Flight Recorder和jcmd实用程序,用于诊断JVM和Java应用程序的问题。 It is suggested to use the latest utility, jcmd instead of the previous jstack utility for enhanced diagnostics and reduced performance overhead. 建议使用最新的实用程序jcmd代替以前的jstack实用程序,以增强诊断并降低性能开销。

However, shipping this with the application may be licensing implications which I am not sure. 但是,随应用程序运送此产品可能会产生许可影响,我不确定。

如果它是* nix我会尝试kill -3 <PID> ,但是你需要知道进程ID,也许你无法访问控制台?

I'd suggest you do all the heap analysis on a staging environment if there is such an env, then reflect your required Application Server tuning on production if any. 如果有这样的环境,我建议你在暂存环境中进行所有堆分析,然后反映你所需的Application Server调整生产(如果有的话)。 If you need the dumps for analysis of your application's memory utilization, then perhaps you should consider profiling it for a better analysis. 如果您需要转储来分析应用程序的内存利用率,那么您可能应该考虑对其进行分析以获得更好的分析。

Heap dumps are usually generated as a result of OutOfMemoryExceptions resulting from memory leaks and bad memory management. 堆转储通常是由于内存泄漏和内存管理不良导致的OutOfMemoryExceptions而生成的。

Check your Application Server's documentation, most modern servers have means for producing dumps at runtime aside from the normal cause I mentioned earlier, the resulting dump might be vendor specific though. 检查Application Server的文档,大多数现代服务器都有在运行时生成转储的方法,除了我之前提到的正常原因之外,生成的转储可能是特定于供应商的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM