2011-10-07 256 views
30

我正在運行使用Hibernate和glassfish服務器的Java Web應用程序。我得到PermGen空間錯誤 - Glassfish服務器

java.lang.OutOfMemoryError: PermGen space例外,當我部署它幾次。我試過-XX:MaxPermSize=128M在我的環境變量,但它不起作用。

+0

這是你在找什麼:http://stackoverflow.com/questions/1996088/java-class-permgen-memory-leak-web-applications-generic-solution – Raedwald

回答

37

這是類加載器的內存泄漏。每次重新部署應用程序時,都會爲其創建一個新的類加載器,並且您的應用程序的所有類都會再次加載。這會消耗perm gen空間中的內存。

舊的類加載器及其所有加載的類必須進行垃圾回收,否則在部署多次後最終會運行到PermGen空間OOME。如果由外部類加載器加載的對象持有對由舊類加載器加載的任何對象的引用,則這不起作用。 This article給出了一個很好的解釋。

一般來說,類加載器泄漏難以分析,有時難以修復。 要找出爲什麼舊的類加載器不是垃圾收集,您必須使用一個分析器。在JProfiler中,使用heap walker,選擇glassfish類加載器對象並使用傳入引用視圖來檢查垃圾收集器根的路徑。

類加載器類被稱爲org.apache.servlet.jasper.JasperLoader。下面是常規情況的屏幕截圖,其中類加載器僅由加載對象的活動實例持有。

enter image description here

在你的情況,你應該看到從外部對象的引用。 Web容器中的類加載器泄漏的另一個常見原因是未停止的後臺線程。例如Google Guice在3.0中有這樣的錯誤。

(免責聲明:我公司開發的JProfiler)

46

爲了解決這個問題(在基於Linux的操作系統)就以下

1)增加內存(使這一問題不經常來)由配置「域。XML」在

/的glassfish /域/域1 /配置

搜索

<jvm-options>-XX:MaxPermSize=

set it to higher value eg- 198m or 256m

2)殺死了GlassFish過程以釋放在其上正在運行的端口(在我的情況下,它是8686) 開放終端(在基於Linux的操作系統)和類型 -

sudo netstat -npl | grep 8686

這將導致類似..

tcp6 0 0 :::8686 :::* LISTEN 3452/java

下次使用

kill -9 3452殺死(在這種情況下,3452),該過程

現在嘗試啓動玻璃魚,它應該開始。

+0

謝謝先生!很好! –

9

如果您使用的是Windows,請嘗試使用任務管理器終止glassfish進程(java.exe * 32),然後重新啓動服務器。

+0

這是完美的 –