相似配置的不同記憶體消耗
我在兩個不同的伺服器(oracle jdk7)上有兩個不同的tomcat 7實例,硬體配置幾乎相同(都> 24 GB RAM)。兩個 tomcat 伺服器具有相同的配置,並且在這些伺服器上部署了相同的 Web 應用程序。catalina opts 如下:
-XX:PermSize=128m -XX:MaxPermSize=512M -Xmx2048m -XX:+CMSIncrementalMode -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC
在執行負載測試時(使用大量並行執行的請求對 REST API 施加壓力)其中一個伺服器拋出異常
java.lang.OutOfMemoryError: Java heap space
(這裡是堆棧跟踪:http: //pastebin.com/wuS1MVCC),另一台伺服器工作正常。我不知道,為什麼會這樣。有沒有人遇到過類似的問題?
因此,您的一個 Tomcat JVM 正試圖超過您為其分配的 2048 MB 堆。
聽起來你正在尋找一個具體的答案,就像一個要嘗試的事情清單一樣,所以你去:
堆用完要麼是由於記憶體洩漏,每次請求都會洩漏一點點,要麼是在負載情況下,這可能是因為你在 JVM 上扔的東西超出了它的處理能力。您想確定哪些是問題所在,因此首先要查看如何生成負載。
如果問題只出現在高級別的並行請求上,而從來沒有出現在低級別的並行請求上,那麼你的問題是請求數乘以處理每個請求所需的記憶體太大了。您要麼需要使每個請求使用更少的記憶體,要麼以某種方式限制並發。
如果在處理了一定數量的請求後出現問題,而不管並發性如何,那麼您就有記憶體洩漏。您需要找到它並回收記憶體。
在任何一種情況下,擁有一個好的堆記憶體分析器都會為您提供很大幫助。有像 YourKit Java Profiler 這樣好的商業工具,或者像 Eclipse Memory Analyzer 這樣的免費工具。找到適合您的工具並學習如何使用它來查看佔用記憶體的內容。請注意,您不一定需要使用該工具來啟動您的程序——如果您在伺服器上執行負載測試,那麼您可以使用 JDK 中的 jmap 命令行工具來擷取文件中的堆轉儲,然後使用您的工具分析轉儲文件。該工具將向您顯示哪些對象正在佔用您的堆空間。