1. 程式人生 > >java.lang.OutOfMemoryError:PermGenspace 持久代溢位解決方法

java.lang.OutOfMemoryError:PermGenspace 持久代溢位解決方法

       前段時間進行專案遷移的時候,遇見java.lang.OutOfMemoryError:PermGenspace,在網上查閱了相關的資料以及解決方案,在這裡記錄下來,方便以後查閱。

 java 堆記憶體分為兩塊,Permanent Space 和Heap Space

  • Permanent 即 持久代(Permanent Generation),主要存放的是Java類定義資訊,與垃圾收集器要收集的Java物件關係不大。
  • Heap = { Old + NEW = {Eden, from, to} },Old 即 年老代(Old Generation),New 即 年輕代(Young Generation)。年老代和年輕代的劃分對垃圾收集影響比較大。

年老代

在年輕代中經歷了N次(可配置)垃圾回收後仍然存活的物件,就會被複制到年老代中。因此,可以認為年老代中存放的都是一些生命週期較長的物件。

針對年老代的垃圾回收即 Full GC。

持久代

用於存放靜態型別資料,如 Java Class, Method 等。持久代對垃圾回收沒有顯著影響。但是有些應用可能動態生成或呼叫一些Class,例如 Hibernate CGLib 等,在這種時候往往需要設定一個比較大的持久代空間來存放這些執行過程中動態增加的型別。

OOM(“Out of Memory”)異常一般主要有如下2種原因

1. 年老代溢位,表現為:java.lang.OutOfMemoryError:Javaheapspace

這是最常見的情況,產生的原因可能是:設定的記憶體引數Xmx過小或程式的記憶體洩露及使用不當問題。

例如迴圈上萬次的字串處理、建立上千萬個物件、在一段程式碼內申請上百M甚至上G的記憶體。還有的時候雖然不會報記憶體溢位,卻會使系統不間斷的垃圾回收,也無法處理其它請求。這種情況下除了檢查程式、列印堆記憶體等方法排查,還可以藉助一些記憶體分析工具,比如MAT就很不錯。


2. 持久代溢位,表現為:java.lang.OutOfMemoryError:PermGenspace

通常由於持久代設定過小,動態載入了大量Java類而導致溢位,解決辦法唯有將引數 -XX:MaxPermSize 調大(一般256m能滿足絕大多數應用程式需求)。將部分Java類放到容器共享區(例如Tomcat share lib)去載入的辦法也是一個思路,但前提是容器裡部署了多個應用,且這些應用有大量的共享類庫。

解決方案

在linux 下修改/data/tomcat/bin/catalina.sh
在“echo "Using CATALINA_BASE:   $CATALINA_BASE"”上面加入以下行:
JAVA_OPTS="-server -XX:PermSize=256M -XX:MaxPermSize=512m"

    ----------------------------------------------------------------------------------------------------------------------------

更詳細資料請參考:https://blog.csdn.net/kthq/article/details/8618052