2012-07-25 35 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。