2017-08-24 89 views
0

我已經閱讀了大量的文章,但很明顯我錯過了我的理解。我有一個Tomcat服務,它安裝有:Tomcat的服務內存超過了最大值,沒有失敗

--JvmMx=1000 
--JvmMs=128 

我已經驗證,這些設置都可以通過電話,如成功:

PsExec.exe -s {jdk}\bin\jinfo.exe -flag MaxHeapSize {pid} 

然而,該服務始終如一的tomcat7.exe過程增長,超過這個最大的因素3或更多,直到它帶來的服務器爬行。奇怪的是,這只是一臺服務器上的問題。在其他地方它是相當穩定的並且保持在極限之下。我也在我的開發環境中尋找內存泄漏,但沒有發現任何內存泄漏。

要調試這一點,我已經試過迫使GC像這樣:

PsExec.exe -s {jdk}\bin\jcmd.exe {pid} GC.run 

但這似乎沒有任何效果。所以接下來我將它設置爲JConsole監視加入這個到安裝:

tomcat7.exe //US//%SERVICE_NAME% ++JvmOptions="-Dcom.sun.management.jmxremote" 
tomcat7.exe //US//%SERVICE_NAME% ++JvmOptions="-Dcom.sun.management.jmxremote.port=8086" 
tomcat7.exe //US//%SERVICE_NAME% ++JvmOptions="-Dcom.sun.management.jmxremote.ssl=false" 
tomcat7.exe //US//%SERVICE_NAME% ++JvmOptions="-Dcom.sun.management.jmxremote.authenticate=false" 

現在是乖巧的(當然!)。 GC顯然工作並且進程內存低於限制。

我很困惑。最大堆是1 GB,永久內存是90 MB,堆棧大小是默認的,那麼大約128KB?線程數量不增長,僅爲「67」。那麼進程內存如何能夠升至3+ GB呢?爲什麼它不拋出內存異常?

即使現在,根據jconsole的「良好行爲」服務僅使用大約50 MB的堆,運行在57個線程上。然而任務管理器顯示使用800 MB的71個線程。我認爲差異是由於Tomcat,是嗎?請幫我填補我的理解空白。

回答

1

Java使用比你需要的東西的Java堆空間更多的內存。它被稱爲「本地內存」,並不包含在您提及/檢查的任何內存空間中。

這個職位將打開你的眼睛: http://www.evanjones.ca/java-native-leak-bug.html

(FWIW,對於一個服務器進程設置-Xms-Xmx不同的價值觀根本就是浪費時間將它們設置爲相同的值,使堆沒有按」。如果你打算在服務器進程中配置1GiB,那麼你可以立即使用它。)

+0

感謝您的鏈接。那很有意思!雖然我不知道它是否適用於此。該服務大多未被使用,因此它只是通過檢查數據庫以執行並記錄狀態來循環。當然沒有太多的併發。我想DB調用可能是本地的。 JVM代碼會變得如此之大似乎很奇怪。有沒有辦法限制這種增長? – Didjit

+0

至於你Xms/Xmx點,是的,我完全同意。 – Didjit

+0

@Didjit我無法知道如何限制JVM使用的本機內存的大小,而不限制OS級別的進程內存 - 如果它超過了限制,這當然會終止進程。它實際上不會讓JVM保持在這樣的限制之下。 –

相關問題