2012-04-12 75 views
2

我在使用Spring + Hibernate的Web應用程序中遇到問題。java.lang.OutOfMemoryError:超出GC開銷限制Spring Hibernate Tomcat 6

我隨機得到錯誤

java.lang.OutOfMemoryError:當Web應用程序在Tomcat上運行GC開銷超過限制

我試圖讓堆轉儲,做堆轉儲的分析使用Eclipse MAT

這裏是我的發現

對象org.hibernate.impl.SessionFactoryObjectFac tory擁有86%的內存,該對象的Fashhashmap實例擁有超過100000個HashMap。 的每一個的Hashmap內有org.hibernate.impl.SessionFactoryImpl的一個實例, 看來org.hibernate.impl.SessionFactoryImpl加載幾次,存儲org.hibernate.impl.SessionFactoryObjectFactory的內部Fashhashmap

能有人幫我找到這個問題的根本原因,並提出一些解決方案來解決這個問題。

+2

你能告訴我們如何在Spring中配置Hibernate嗎?你如何管理事務和一些Hibernate示例查詢?可以匿名。 – 2012-04-12 17:47:57

回答

1

那麼,即使你得到那SessionFactoryObjectFactory holds 86% of the memory,它似乎不是我的原因。第一件事是在依賴任何內存分析工具之前,我們應該首先了解這個工具如何預測出outofmemory問題。 內存工具只是試圖捕獲運行該工具後顯示在應用程序中的即時HIKES。我很肯定你會得到相同的錯誤日誌,但是由於工具提到Catalina web class loader正在訪問大量內存,這是顯而易見的和預期的。

所以我只是想弄清楚,而不是依賴任何這樣的工具(這可能適用於特定的案例/實現),您嘗試挖掘您的應用源代碼並嘗試找到不必要的臨時對象在哪裏創建。

出於調試目的,您可以打開JVM選項 - -XX:-PrintGCDetails來查看GC正在收集什麼。

查看這些信息/更多信息參考 - 更多的處理器時間http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html#Options java.lang.OutOfMemoryError: GC overhead limit exceeded

0

嗯,你的GC線程花費98%或試圖清理對象。

工廠模式的想法是返回一個你想創建的對象的非空實例,這通常是通過一旦實例化後返回同一個實例來完成的。

現在它可能是你有100,000個不同的會話或什麼,但我懷疑這是正確的,因此你需要檢查你的代碼,以確保Factory方法調用正確關閉,並且可能沒有本地副本緩存。

如果確實有100,000個會話,請仔細看看創建它們的方法。打破長期的方法,以便循環和結構通過方法調用分開,以便方法局部變量可以在範圍外清除。

此外,請確保這些較小的方法不是最終的,因爲編譯器會將最終方法拼接成單個堆棧幀作爲優化技術。