在生产中进行线程转储

时间:2013-01-02 07:32:48

标签: java runtime.exec thread-dump

我正在分析获取线程转储的方法之间的差异。以下是我正在研究的几个人

  1. 定义一个jmx bean,它在单击声明的bean操作时通过Runtime.exec()触发jstack。

  2. 守护程序线程在预定义的时间间隔后重复执行“ManagementFactory.getThreadMXBean()。dumpAllThreads(true,true)”。

  3. 比较两者之间的线程转储输出,我在方法2中看到了以下缺点

    1. 使用方法2记录的线程转储无法由开源线程转储分析器(如TDA
    2. )解析
    3. 输出不包括原生线程ID,这可能对分析高CPU问题很有用(对吗?)
    4. 还有吗?
    5. 我很高兴收到

      的建议/意见
      1. 在生产代码中通过Runtime.exec()执行jstack是否有任何缺点?各种操作系统上的兼容性问题 - windows,linux?

      2. 采取线程转储的其他方法吗?

      3. 谢谢。

        修改

        1和2的组合方法似乎是要走的路。我们可以在后台运行专用线程,并以线程转储分析器可以理解的格式在日志文件中打印线程转储。 如果需要任何额外的信息(比如说可能是本机线程id)只能由jstack输出记录,我们会根据需要手动执行。

4 个答案:

答案 0 :(得分:32)

您可以使用

jstack {pid} > stack-trace.log

在进程正在运行的框中以用户身份运行。

如果您多次运行此操作,则可以使用diff更轻松地查看哪些线程处于活动状态。


为了分析堆栈跟踪,我在专用线程中定期使用以下采样。<​​/ p>

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

使用此信息,您可以获取线程的id,运行状态并比较堆栈跟踪。

答案 1 :(得分:7)

使用Java 8,jcmd是首选方法。

jcmd <PID> Thread.print

以下是Oracle documentation的摘要:

JDK 8的发布引入了Java Mission Control,Java Flight Recorder和jcmd实用程序,用于诊断JVM和Java应用程序的问题。 建议使用最新的实用程序jcmd代替以前的jstack实用程序,以增强诊断并降低性能开销。

但是,将此与应用程序一起发送可能会产生许可问题,我不确定。

答案 2 :(得分:4)

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

答案 3 :(得分:0)

如果有这样的环境,我建议你在暂存环境中进行所有堆分析,然后反映你所需的Application Server调整生产(如果有的话)。如果您需要转储来分析应用程序的内存利用率,那么您可能应该考虑对其进行分析以获得更好的分析。

堆转储通常是由于内存泄漏和内存管理不良导致的OutOfMemoryExceptions生成的。

检查Application Server的文档,大多数现代服务器都有在运行时生成转储的方法,除了我之前提到的正常原因,结果转储可能是特定于供应商的。