前幾天公司一個項目的服務器壞了,就換了一個備份服務器頂替一下,但是沒有跑一會就宕機了,一直報java.lang.OutOfMemoryError。。。。一看到這里,就知道是內存溢出,但是JBoss的內存配置已經達到1024M了,而且對JBoss內存的監測結果看,并不高,怎么會死機呢,好奇怪。搞了半天還是沒有結果。郁悶~~~~
到了最后,已經絕望了我,打算換一個JBoss版本,再換一個JDK,看看是不是這些的問題。但是再換以前,我就把日志又重新看了一次,發現一個問題。報的java.lang.OutOfMemoryError后面還有內容:java.lang.OutOfMemoryError: PermGen space,這個好像和java.lang.OutOfMemoryError: Java heap space這個不一樣。最后找了一下這個異常!
PermGen space的全稱是Permanent Generation space,是指內存的永久保存區域。這一部分用于存放Class和Meta的信息,Class在被 Load的時候被放入PermGen space區域,它和和存放Instance的Heap區域不同,GC(Garbage Collection)不會在主程序運行期對PermGen space進行清理,所以如果你的APP會LOAD很多CLASS的話,就很可能出現PermGen space錯誤。這種錯誤常見在web服務器對JSP進行pre compile的時候。
改正方法,在 run.bat 中加入:-Xms512m -Xmx1024m -XX:MaxNewSize=256m -XX:MaxPermSize=256m
因為項目中引用了很多的 jar 包,而這些 jar 包中的 class 信息會被 JBoss 的 class loader 加載到 PermGen space 區域,在 JVM 默認的情況下,該部分空間的大小只有 4M,在 jar 包非常多的情況下,顯然是不夠用的,所以通過 -XX:MaxPermSize=256m 指定最大值后即可解決問題。
我的JBoss里面裝載了6個應用,jar包和class加起來有100m左右,配上這個參數后,一切OK,最后服務器修好以后,發現,這個里面的JBoss也是這么來配置的,哎~~看來以后備份,最好還是吧JBoss一起備份出來吧!
而當出現出現 java.lang.OutOfMemoryError: Java heap space 這個異常時,通過調節-Xms512m -Xmx1024m這個就可以解決。
另外,這個兩個參數 -XX:+UseParallelGC -XX:+UseParallelOldGC 讓服務并行回收內存空間。但是,這兩個參數配置上去以后,也會占用一定的內存空間。