2012-07-25 114 views
8

我想为JVM创建一个nagios看门狗,看看JVM何时耗尽内存并重新启动它。如何使用JMX监控在内存不足时重新启动JVM?

目前我能够设置JVM允许JMX,但我不知道如何检测OutOfMemory条件并重新启动它。

/check_jmx -U service:jmx:rmi:///jndi/rmi://127.0.0.1:1100/jmxrmi -O "java.lang:type=Memory" -A "HeapMemoryUsage" -K used -I HeapMemoryUsage -J used -vvvv 
JMX OK HeapMemoryUsage.used=957414288{committed=2415984640;init=2147483648;max=2863333376;used=957414288} 

https://github.com/tcurdt/nagios-check-jmx

+1

不幸的是,标准的jdk无法检测到jvm已经命中了OOM。在我们的产品中经历了这个。我最终安装了一个日志处理程序,它检查包含OOME的LogRecords。只要没有代码吞下错误而不报告它就可以工作。 – jtahlborn 2012-07-25 16:42:31

+0

我确实通过java工具API找到了一些有前途的API,但是我总结出任何解决方案都会涉及在工具代理中实现本机代码,这对我们来说是“不行”。 – jtahlborn 2012-07-25 16:45:22

回答

1

我不认为你要能够检测使用JMX内存不足的条件。如果JVM真的处于其生命的尽头,那么当您尝试连接时,JMX连接很可能会自行抛出OOM异常。

我们检测到内存条件而不是OOM。当我们的系统的可用内存低于某个水印一段时间时,我们会发出警报。我们还有一些线程运行以转储每个服务的指标文件。由于线程已经分配,​​所以在JVM用完之后它可以可靠地转储系统内存信息。

我们记录:

// free memory 
Runtime.getRuntime().freeMemory() 
// current heap usage 
Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory() 
+3

如果你想知道你是否开始用尽可用内存,你不需要使用'Runtime.getRuntime()。maxMemory()'?因为'totalMemory()'是基于JVM在那个时候JVM所具有的东西(即它可以增长)。基本上可用的内存是'Runtime.getRuntime()。maxMemory() - Runtime.getRuntime()。totalMemory()+ Runtime.getRuntime()。freeMemory() '。 – 2012-07-25 17:29:56

12

如果您使用的是Java 1.4.2或更高版本,此选项可让您在发生第一OutOfMemeory例外执行用户自定义命令:-XX:OnOutOfMemoryError="<cmd args>;<cmd args>"

应给你一些体面的选择。例如你可以启动一个被动检查来告诉nagios服务器正在重新启动,然后启动一个shell脚本来停止/启动错误的JVM。

相关问题