1. 程式人生 > >JVM之記憶體溢位的幾種情況以及可以採取的解決方案

JVM之記憶體溢位的幾種情況以及可以採取的解決方案

開發中遇到過以下三種記憶體溢位的狀況:

一、 java.lang.OutOfMemoryError: Java heap space

二、 java.lang.OutOfMemoryError: PermGen space

三、 java.lang.OutOfMemoryError: GC overhead limit exceeded

詳述:


一、Java heap space(堆記憶體溢位)

Java應用程式建立的物件存放在這片區域

垃圾回收(Garbage Collection)也發生在這塊區域

建立大量的物件,可能會導致記憶體溢位

層次比較深的遞迴操作,可能會導致記憶體溢位

解決方案一般有以下兩種:

1、優化應用,比如找到建立大量物件的程式碼塊,進行優化。

2、提升Java heap size

比如在tomcat的catalina.bat裡面加入以下資訊:

在以下程式碼塊的下面新增即可:

 set MAINCLASS=org.apache.catalina.startup.Bootstrap
 set ACTION=start
 set SECURITY_POLICY_FILE=
 set DEBUG_OPTS=
 set JPDA=

set CATALINA_OPTS=-Xms512m   -Xmx512m


二、PermGen space

在以下程式碼塊的下面新增即可:

 set MAINCLASS=org.apache.catalina.startup.Bootstrap
 set ACTION=start
 set SECURITY_POLICY_FILE=
 set DEBUG_OPTS=
 set JPDA=
set CATALINA_OPTS=-server -Xms256m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=512m

三、GC overhead limit exceeded

這個錯誤會出現在這個場景中:GC佔用了多餘98%(預設值)的CPU時間卻只回收了少於2%(預設值)的堆空間。

一般是應用程式在有限的記憶體上建立了大量的臨時物件或者弱引用物件,從而導致該異常

 

解決方法

JVM引數

JVM給出一個引數避免這個錯誤:-XX:-UseGCOverheadLimit

但是,這個引數並不是解決了記憶體不足的問題,只是將錯誤發生時間延後,並且替換成java.lang.OutOfMemoryError: Java heap space

堆記憶體

還有一個偷懶的方法是:增大堆記憶體。既然堆記憶體少了,那就增加堆記憶體即可。

但是,這個方法也不是萬能的。因為程式裡可能有記憶體洩露。這個時候即使再增大堆記憶體,也會有用完的時候。

所以前兩個方法都只是治標不治本而已。

終極方法

有一個終極方法,是治標治本的方法,就是找到佔用記憶體大的地方,把程式碼優化了,就不會出現這個問題了。