OutOfMemoryError

第一種OutOfMemoryError: PermGen space (永久保存區域)

Permanent Generation space

PermGen space的全稱是Permanent Generation 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)那麼就會產生此錯誤信息了

 

Generation space有關。解決這類問題有以下兩種辦法:

1. 增加java虛擬機中的XX:PermSize和XX:MaxPermSize參數的大小,其中XX:PermSize是初始永久保存區域大小,XX:MaxPermSize是最大永久保存區域大小。如針對tomcat6.0,在catalina.sh 或catalina.bat文件中一系列環境變量名說明結束處(大約在70行左右) 增加一行:

JAVA_OPTS=" -XX:PermSize=64M -XX:MaxPermSize=128m"

如果是windows服務器還可以在系統環境變量中設置。感覺用tomcat發佈sprint+struts+hibernate架構的程序時很容易發生這種內存溢出錯誤。使用上述方法,我成功解決了部署ssh項目的tomcat服務器經常宕機的問題。

2. 清理應用程序中web-inf/lib下的jar,如果tomcat部署了多個應用,很多應用都使用了相同的jar,可以將共同的jar移到tomcat共同的lib下,減少類的重複加載。這種方法是網上部分人推薦的,我沒試過,但感覺減少不了太大的空間,最靠譜的還是第一種方法。

 

 

 

 

第二種OutOfMemoryError:  Java heap space (堆區域)

 

發生這種問題的原因是java虛擬機創建的對象太多,在進行垃圾回收之間,虛擬機分配的到堆內存空間已經用滿了,與Heap space有關。

 

比如下面代碼就會產生此種情況的內存溢出。

 

Set<Object> set = new HashSet<Object>();

 

for (int i = 0; i < 100000000; i++) {

 

set.add(new Object());

 

}

 

 

 

解決這類問題有兩種思路:

 

1. 檢查程序,看是否有死循環或不必要地重複創建大量對象。找到原因後,修改程序和算法。

 

我以前寫一個使用K-Means文本聚類算法對幾萬條文本記錄(每條記錄的特徵向量大約10來個)進行文本聚類時,由於程序細節上有問題,就導致了Java heap space的內存溢出問題,後來通過修改程序得到了解決。

 

2. 增加Java虛擬機中Xms(初始堆大小)和Xmx(最大堆大小)參數的大小。如:set JAVA_OPTS= -Xms256m -Xmx1024m

 

 

 

 

 

第三種OutOfMemoryError:unable to create new native thread

 

 

 

上面這種種溢出錯誤,已經說明了線程的內存空間,其實線程基本只佔用heap以外的內存區域,也就是這個錯誤說明除了heap以外的區域,無法爲線程分配一塊內存區域了,這個要麼是內存本身就不夠,要麼heap的空間設置得太大了,導致了剩餘的內存已經不多了,而由於線程本身要佔用內存,所以就不夠用了。

 

 

 

 RUNTIME 類的使用:
 
Java 給我們提供了Runtime 類得到JVM 內存的信息
 方法名稱  參數 作用  返回值 
 getRuntime   無  獲取Runtime 對象   Runtime 對象 
 totalMemory   無  獲取JVM 分配給程序的內存數量   long:內存數量 
 freeMemory  無  獲取當前可用的內存數量   long:內存數量 
 maxMemory   無  獲取JVM 可以申請到的最大內存數量  long:內存數量 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章