TL; DR:我可以从我的主JVM中检测到通过2个中间脚本生成的从属JVM在Linux上遇到OutOfMemory错误的万无一失(!)方法吗?
长版:
我正在运行某种应用程序启动器。基本上它接收一些输入并通过产生一个从属Java应用程序来处理所述输入作出反应。这通过python脚本(为了正确处理它的远程kill命令)发生,而脚本又调用bash脚本(由Gradle生成并设置类路径)来实际生成slave。 从属设备包含一个工作线程和一个监视器线程,用于回调远程主机以进行状态更新。如果状态更新未能在设定的时间内发生,则从属设备将被启动器杀死。它没有响应的原因可能是OutOfMemoryError,但它也可能是其他原因。我需要区分从属的OutOfMemoryError和导致它停止工作的其他错误。 我不只是想监视内存使用情况,并说一旦达到90%“确定就够了”。 GC很可能成功地完成了清理工作以完成工作量。我只想知道它是否未能清理并且JVM死亡,因为没有足够的内存可以被释放。
我尝试过:
使用-XX:OnOutOfMemory标志作为从属的JVM选项,该选项调用脚本,该脚本又创建空标志文件。然后,如果奴隶死了,我会检查启动器是否存在标志文件。在Windows上工作就像一个魅力,在Unix上根本不起作用,因为有一个时髦的错误导致执行标志调用需要与奴隶使用完全相同的Xmx数量。有关错误,请参阅https://bugs.openjdk.java.net/browse/JDK-8027434。 =>解决方案被丢弃,因为从站需要机器的整个内存。
try{ longWork(); } catch (OutOfMemoryError e) { createOomFlagFile(); System.exit(100); }
这在某些情况下有效。但是,也有一些情况,这种情况不会发生,监视器线程只是停止发送状态更新。没有异常发生,没有创建OOM标志文件。我知道从SSH到机器虽然Java正在占用系统上所有可用的内存而且整个系统都很慢。
是否有一些(优雅的)万无一失的方式来检测我遗漏的内容?
答案 0 :(得分:2)
您不应该等待OutOfMemory。我的建议是,您通过Java Management Beans跟踪主应用程序的内存消耗,并在内存消耗变得严重时发出警告。我之前从未这样做过,所以我无法更准确地了解如何做到这一点,但也许你发现或其他一些人可以提供解决方案。
修改:这是相应的MXBean http://docs.oracle.com/javase/7/docs/api/java/lang/management/MemoryMXBean.html