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
。
堆記憶體
還有一個偷懶的方法是:增大堆記憶體。既然堆記憶體少了,那就增加堆記憶體即可。
但是,這個方法也不是萬能的。因為程式裡可能有記憶體洩露。這個時候即使再增大堆記憶體,也會有用完的時候。
所以前兩個方法都只是治標不治本而已。
終極方法
有一個終極方法,是治標治本的方法,就是找到佔用記憶體大的地方,把程式碼優化了,就不會出現這個問題了。