java.lang.OutOfMemoryError及解決方案

主要有3種比較常見的OutOfMemory Error:

java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: PermGen space
java.lang.OutOfMemoryError: GC overhead limit exceeded


1. java.lang.OutOfMemoryError: Java heap space

     Java heap space,Java應用程序創建的對象存放在這片區域,垃圾回收(Garbage Collection)也發生在這塊區域。通常一些比較“重型”的操作可能會導致該異常,比如:需要創建大量的對象,層次比較深的遞歸操作等。
     解決方案有兩種,一是優化應用,找到消耗大量內存的地方,然後優化代碼或者算法。這種方式比較推薦,但是難度比較大,尤其是在產品環境中出現這種問題,開發人員不能很好的重現問題。第二種方案是提升Java heap size,這種方式雖然感覺有點治標不治本,但是可行性非常高,操作簡單。
     對於一般的應用,採用如下方式即可(數字根據自己的需要調整),解決辦法:

 “JVM 堆空間溢出(java.lang.OutOfMemoryError: Java heap space)”錯誤是JVM 堆空間不足,此時只需要調整-Xms 和-Xmx 這兩個參數即可。

linux中在{tomcat_dir}/bin/catalina.sh :

export  JAVA_OPTS="-Xms512m -Xmx2048m -Xss1024K -XX:PermSize=512m -XX:MaxPermSize=512m"
export  CATALINA_OPTS="-Xms512m -Xmx2048m -Xss1024K -XX:PermSize=512m -XX:MaxPermSize=512m"


windows在{tomcat_dir}/bin/catalina.bat中找到如下幾行:

set JAVA_OPTS=-server -Xms512m -Xmx1024m -XX:PermSize=128m -XX:MaxNewSize=256m -XX:MaxPermSize=256m
set CATALINA_OPTS=-server -Xms512m -Xmx1024m -XX:PermSize=128m  -XX:MaxPermSize=256m


2. java.lang.OutOfMemoryError: PermGen space

  ”永久存儲區溢出 PermGen space的全稱是Permanent Generation space“  或“(java.lang.OutOfMemoryError:Java Permanent Space)”,都是指內存的永久保存區域,乃是永久存儲區設置太小,不能滿足系統需要的大小,此時只需要調整-XX:PermSize 和-XX:MaxPermSize 這兩個參數即可。

    “PermGen space”這塊內存主要是被JVM存放Class和Meta信息的,Class在被Loader時就會被放到PermGen space中, 它和存放類實例(Instance)的Heap區域不同,GC(Garbage Collection)不會在主程序運行期對PermGen space進行清理,所以如果你的應用中有很多CLASS的話,就很可能出現PermGen space錯誤, 這種錯誤常見在web服務器對JSP進行pre compile的時候。如果你的WEB APP下都用了大量的第三方jar, 其大小超過了jvm默認的大小(4M)那麼就會產生此錯誤信息了。

解決辦法:

linux在在{tomcat_dir}/bin/catalina.sh:

export  JAVA_OPTS="-Xms512m -Xmx2048m -Xss1024K -XX:PermSize=512m -XX:MaxPermSize=512m"
export CATALINA_OPTS="-Xms512m -Xmx2048m -Xss1024K -XX:PermSize=512m -XX:MaxPermSize=512m"

windows在{tomcat_dir}/bin/catalina.bat中添加如下一行:

set JAVA_OPTS=-server -Xms256m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=512m
set CATALINA_OPTS=-server -Xms256m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=512m


3. java.lang.OutOfMemoryError: GC overhead limit exceeded

     這個錯誤會出現在這個場景中:GC佔用了多餘98%(默認值)的CPU時間卻只回收了少於2%(默認值)的堆空間。目的是爲了讓應用終止,給開發者機會去診斷問題。一般是應用程序在有限的內存上創建了大量的臨時對象或者弱引用對象,從而導致該異常。雖然加大內存可以暫時解決這個問題,但是還是強烈建議去優化代碼,後者更加有效。


4. CATALINA_OPTS和JAVA_OPTS區別

有兩個環境變量 - CATALINA_OPTS和JAVA_OPTS- 都用於Tomcat 的catalina.sh啓動和關閉腳本。它們在該文件中的註釋中描述爲:

[JAVA_OPTS] :(可選)執行“start”,“stop”或“run”命令時使用的Java運行時選項

[CATALINA_OPTS] :(可選)執行“start”或“run”命令時使用的Java運行時選項

那麼爲什麼有兩個不同的變量呢?有什麼區別?

首先,在EITHER變量中指定的任何內容都以相同的方式傳遞給啓動Tomcat的命令 - “start”或“run”命令 - 但只有在JAVA_OPTS中設置的值纔會傳遞給“stop”命令。這可能對Tomcat在實踐中的運行方式沒有任何影響,因爲它隻影響運行的結束,而不是開始。

第二個區別更微妙。其他應用程序也可以使用JAVA_OPTS,但只有Tomcat纔會使用CATALINA_OPTS。因此,如果您設置的環境變量僅供Tomcat使用,那麼最好建議您使用CATALINA_OPTS,而如果您正在設置環境變量以供其他Java應用程序使用,例如JBoss,您應該放置您在JAVA_OPTS中的設置。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章