Java似乎挂了

我一直在自定义应用程序中使用Java Service包装器已经有一段时间了,它一直运行良好。 由于在最近几天将我们的应用程序更新到新版本,JVM开始挂起,然后包装器在日志中打印出来:JVM出现挂起:超时等待来自JVM的信号。

然后它会自动终止JVM并再次启动应用程序。 这在大约10个小时的运行后发生,这使得调试变得更加困难。

当然,我将查看我们所做的更改,但没有做出重大更改,我怀疑是会导致此类问题。

我在哪里可以尝试找出发生了什么? 来自应用程序的调试消息不表示任何有趣的内容。 如果JVM刚崩溃,它通常会创建一个转储,这可以帮助调试它,但它是挂起的,所以它不会创建转储。 如果我没有自动重启服务,那么在重新启动它之前我可以做些什么来从JVM中获取一些有用的信息?

在我看来,JVM不应该挂起典型的编程错误。 你之前遇到什么会导致JVM挂起?

阅读wrapper.ping.timeout属性 。 包装器软件经常与您的JVM通信,以确保它是活着的。 如果该通信因任何原因而失败,则包装器会认为该进程已挂起并尝试重新启动它。

根据应用程序的架构方式,当包装器尝试“ping”它时,JVM可能正忙于处理其他内容。

看看您是否可以使用Visual VM查看正在发生的事情。 让Visual VM一直监视应用程序,当它停止工作时,您可以确定出现了什么问题。

如果VM挂起,你可以获得线程的状态…我认为Visual VM会使你的设置比通常的ctrl-break(或者关键组合是什么)更容易。

(根据评论编辑)

试过这个。 上次挂起线程数并且使用的内存量非常低,因此这些都不会导致问题。 不幸的是,在它挂起并且包装器终止后,你无法获得一个线程转储。

有没有办法在没有包装器的情况下运行它来调试它? 此外,如果您使用NetBeans探查器,它可能会让您有机会在它停止时处理它(我将在今天晚些时候检查,看看我是否能够发现它是否会表现不同)。

你在什么环境? OS,JVM版本,硬件架构?

这听起来像一个bug,并且考虑到需要花费很多时间,这听起来像某种资源耗尽的bug。

我在类路径(JBPM)上有几个不同版本的库。 使用包装器,您可以使用通配符来包含jar。 请注意这一点,因为您可能会意外地包含更多内容。

这篇IBM文章提供了有关Java中调试挂起的信息。 它基本上说有两件事可能导致挂起:

  1. 无限循环,
  2. 陷入僵局。

从那时起,我不得不调试其他悬而未决的问题。 在linux上,您可以向JVM发送QUIT信号,使其对控制台进行线程转储。 这确实有助于找出问题所在。 使用此命令执行此操作:kill -QUIT

编辑6/13/2017

这些天我使用JDK中包含的jmap来转储程序的整个内存。 然后我使用Eclipse Memory Analyzer来查看程序崩溃时的确切状态。 您可以查看活动的线程列表,然后检查每个堆栈帧中的变量。

/usr/java/latest/bin/jmap -dump:file=/tmp/app-crash.hprof  

其中PID是java进程的进程ID。