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

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

当然,我会仔细研究一下我们所做的改变,但没有做出重大改变,我怀疑会造成这类问题。

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

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

有帮助吗?

解决方案 4

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

这是一篇IBM文章,提供有关调试在Java中挂起。它基本上说有两件事可能导致挂起:

  1. 无限循环,
  2. 陷入僵局。
  3. 从那时起,我不得不调试其他悬而未决的问题。在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>
    

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

其他提示

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

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

查看您是否可以使用 Visual VM 查看正在发生的情况。让Visual VM一直监视应用程序,当它停止工作时,也许你可以确定错误。

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

(根据评论编辑)

  

试过这个。上次挂了   线程数和数量   使用的内存非常低,所以   这些都没有导致   问题。不幸的是它挂了之后   和包装器终止它你不能   得到一个线程转储。

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

你在哪个环境? OS,JVM版本,硬件架构?

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top