开发中遇到过以下三种内存溢出的状况:
一、 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
。
堆内存
还有一个偷懒的方法是:增大堆内存。既然堆内存少了,那就增加堆内存即可。
但是,这个方法也不是万能的。因为程序里可能有内存泄露。这个时候即使再增大堆内存,也会有用完的时候。
所以前两个方法都只是治标不治本而已。
终极方法
有一个终极方法,是治标治本的方法,就是找到占用内存大的地方,把代码优化了,就不会出现这个问题了。