2010-10-04 85 views
2

我在Sun JVM(1.6.0_21-b06)上收到PermGen空間錯誤(確定,它是Oracle :))。選項-XX:MaxPermGen值的增加沒有幫助。我知道PermGen是一個用於類元數據等永久對象的空間。項目中的課程數量不是很大〜10 000.在崩潰之前,jvisualvm顯示57MB爲使用PermGen。導致java.lang.OutOfMemoryError的算法:PermGen空間錯誤

我想有些算法佔用所有可訪問的內存。有人知道導致PermGen溢出的算法的例子嗎?

UPD。我問這樣一個抽象問題,因爲在那個時候我不能使用任何分析器 - 代碼崩潰如此困難以至於jvisualvm和eclipse停止響應。我需要殺死終端與kill -KILL {process_numer}的java進程。我使用有很多線程和JMS消息傳遞的糟糕的有組織(但商業)代碼。調試是一團糟 - 我首先需要一些想法在哪裏看。

+1

你quesion的抽象級別殺死;)。使用Java分析器(例如virtualvm)來找出程序崩潰的原因。如果您發現問題,請重寫您的問題。 – Skarab 2010-10-04 13:59:17

+0

只是出於好奇,你能顯示你使用的確切的命令行選項嗎? – karoberts 2010-10-04 14:04:45

+0

通過了解導致PermGen溢出的代碼示例,您會達到什麼目的?你是否試圖欣賞一個問題,然後從敬仰中產生問題,或者你是否試圖修復它?我已經看到這個問題解決方法失敗了很多次,最好找到根本原因並解決它。像Skarab建議使用Java分析器。明白如果你是一個研究人員或學生,但看起來不像。 – sjt 2010-10-04 14:25:26

回答

1

Does someone know examples of algorithms that lead to PermGen overflow ?

是的,但是這是什麼意思?如果你想解決這個問題,請安裝一個類似jprobe或lambda探測器的內存分析器工具,並檢查內存泄漏發生的位置,然後解決該問題。現在舉個例子:有成千上萬的方法來超越燙髮空間。我在一個項目中注意到我們繼承了使用JMS的應用程序。 jms連接保持打開狀態,應用程序在收到很多請求後會在幾分鐘內崩潰,並且出現類似的錯誤。值得注意的是:當我們從jboss移動到weblogic(移動到beajrockit)時,它驚人地固定了自己或者至少接受了技術債務的打擊。我的建議將與此無關,應該先修復內存泄漏的錯誤代碼,然後修改應用程序服務器和堆空間分配參數。

這是一個有用的鏈接,包含你所得到的例外信息。 http://www.jroller.com/agileanswers/entry/preventing_java_s_java_lang

編輯

此鏈接可能是有益的 http://www.precisejava.com/javaperf/j2ee/JMS.htm

+0

我認爲在我的情況下,你對JMS的想法是最有前瞻性的。一些消息在崩潰前發送。 – Nulldevice 2010-10-04 15:18:53

+0

關於JMS框架的一點是它是異步的,可以收到幾個異步請求,當jms連接沒有關閉時它可能導致問題。祝你好運。 – sjt 2010-10-04 15:23:23

4

算法不如實現。下面就來生成隨機字符串一個很愚蠢的方式,填補了PermGen的空間:

Random rnd = new Random(); 
    List<String> interned = new ArrayList<String>(); 
    for (;;) { 
     int length = rnd.nextInt(100); 
     StringBuilder builder = new StringBuilder(); 
     String chars = "abcdefghijklmnopqrstuvwxyz"; 
     for (int i = 0; i < length; i++) { 
      builder.append(chars.charAt(rnd.nextInt(chars.length()))); 
     } 
     interned.add(builder.toString().intern()); 
    } 

簡而言之:實習弦一兩件事是可以吃的PermGen內存。

0

您是否使用不同的垃圾收集器?

The throughput collector will throw an out-of-memory exception if too much time is being spent doing garbage collection. For example, if the JVM is spending more than 98% of the total time doing garbage collection and is recovering less than 2% of the heap, it will throw an out-of-memory expection. The implementation of this feature has changed in 1.5. The policy is the same but there may be slight differences in behavior due to the new implementation.」 」 In the J2SE Platform version 1.5 the throughput collector will be chosen as the garbage collector on server class machines.」 http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html

查看this的一些說明頁面。

3

有兩件事情有可能導致PermGen的空間問題:

  1. String.intern(String)方法PermGen的堆創建的字符串。如果您進行了大量實習並直接(或間接)保留對實習字符串的引用,則可以填寫PermGen。

  2. 類加載器在PermGen堆中創建JVM內部類描述符和代碼段。如果您的應用程序執行了大量的動態類加載,並且類對象不會被垃圾回收,則可以填充PermGen。

熱調用Java webapps依賴於動態加載並且是常見的源PermGen問題。根本原因通常是內存泄漏,涉及從某個對象到舊類加載器的隱藏引用。 (Tomcat通常會爲此「堅持」,但真正的問題通常在正在重新部署的webapp中)。

AFAIK,@Michael Borgwardt提到的代理案例也是代理實現生成類文件的結果並在飛行中加載它們。