Java中OutOfmemory的简单检测

Java中OutOfmemory的简单检测,java,Java,TL;DR:有没有一种简单的(!)方法可以从我的主JVM中检测到我的从JVM通过两个中间脚本生成,在Linux上遇到OutOfMemory错误 长版本: 我正在运行某种应用程序启动器。基本上,它接收一些输入,并通过生成一个从Java应用程序来处理所述输入来作出反应。这是通过一个python脚本(正确处理远程kill命令)实现的,该脚本反过来调用一个bash脚本(由Gradle生成并设置类路径)来实际生成从机。 从机包含一个工作线程和一个监视器线程,用于回调远程主机以进行状态更新。如果状态更新在设

TL;DR:有没有一种简单的(!)方法可以从我的主JVM中检测到我的从JVM通过两个中间脚本生成,在Linux上遇到OutOfMemory错误

长版本:

我正在运行某种应用程序启动器。基本上,它接收一些输入,并通过生成一个从Java应用程序来处理所述输入来作出反应。这是通过一个python脚本(正确处理远程kill命令)实现的,该脚本反过来调用一个bash脚本(由Gradle生成并设置类路径)来实际生成从机。 从机包含一个工作线程和一个监视器线程,用于回调远程主机以进行状态更新。如果状态更新在设定的时间内失败,则从机将被启动器杀死。它没有响应的原因可能是OutOfMemoryError,但也可能是其他原因。我需要区分从机的OutOfMemoryError和导致它停止工作的其他错误。 我不只是想监控内存使用情况,并在达到90%时说“好了,就够了”。很可能是GC成功地清理了足够多的工作负载以完成。我只想知道它是否因为无法释放足够的内存而无法清理,JVM是否死亡

我所尝试的:

  • 使用-XX:onAutofMemory标志作为从机的JVM选项,该从机调用一个脚本,该脚本反过来创建一个空标志文件。然后,如果奴隶死了,我会向启动器检查标志文件是否存在。在Windows上工作得很好,但在Unix上根本不起作用,因为存在一个奇怪的错误,导致执行标志调用需要与从机使用的Xmx量完全相同的量。有关错误,请参阅。=>解决方案被丢弃,因为从机需要机器的全部内存

  • try{longWork();}catch(OutOfMemoryError){createOomFlagFile();System.exit(100);}
    在某些情况下确实有效。但是,在某些情况下,这种情况不会发生,监视器线程只是停止发送状态更新。未发生异常,未创建OOM标志文件。尽管Java正在消耗系统上所有可用的内存,但我从机器上的SSHing中知道,整个系统运行缓慢


有什么(优雅的)万无一失的方法来检测我遗漏的信息吗?

你不应该等待记忆的结束。我的建议是,通过Java管理bean跟踪主应用程序的内存消耗,并在内存消耗变得严重时发出警告。我以前从来没有独自做过,所以我无法更准确地了解如何做,但也许你会发现,或者这里的其他人可以提供一个解决方案


编辑:这是相应的MXBean

如果在第二次尝试中没有出现异常,为什么您确定
longWork()
确实因为内存不足而失败?问题是,一旦一段时间没有进行状态更新,无论发生什么情况,从机都会被杀死。然后有必要知道它是否死于内存不足或其他原因。这里有一些例子:仅仅因为内存变得非常低,并不意味着它将a)保持这种状态,或者b)GC将失败。因此,我真的想检测GC是否失败,内存消耗是否会杀死JVM。我现在通过在从机中启动一个监视线程来解决这个问题,该线程通过
Runtime.getTotalMemory()
Runtime.getMaxMemory()
监视内存消耗。MXBean没有用,因为它返回的值与Linux告诉我的值不一致。一旦超过阈值,就会创建一个标志文件。如果从属服务器非自然死亡,启动器将检查标志文件是否存在,并对其执行操作。