1、堆内存溢出
常见堆内存溢出的三种情况。
情况一:
Java.lang.OutOfMemoryError:Javaheap space
原因:这种是java堆内存不够,一个原因是内存真不够,另一个原因是程序中有死循环。
解决方式:有死循环的话调代码就行了,如果是java堆内存不够的话,可以通过适当调大JVM的配置来解决:
<jvm-arg>-Xms3062m</jvm-arg>
<jvm-arg>-Xmx3062m</jvm-arg>
可以适当的往上调整Xms合Xmx的大小,合适即可,不是越大越好。
情况二:
java.lang.OutOfMemoryError: GC overhead limit exceeded
原因:JDK6新增错误类型,当GC为释放很小空间占用大量时间时抛出;一般是因为堆太小,导致异常的原因是没有足够的内存。
解决方式:
- 查看系统是否有使用大内存的代码或死循环,有的话调通。
- 通过添加JVM配置,来限制使用内存。如下:
< jvm-arg>-XX:-UseGCOverheadLimit< /jvm-arg>
情况三:
java.lang.OutOfMemoryError: PermGen space
原因:P区内存不够。
解决方法:调整JVM的配置。如下:
<jvm-arg>-XX:MaxPermSize=128m</jvm-arg>
<jvm-arg>-XXermSize=128m</jvm-arg>
2、栈异常
常见栈异常的两种方情况。
情况一:
java.lang.OutOfMemoryError: unable to create new native thread
原因:Stack空间不足以创建额外的线程,要么是创建的线程过多,要么是Stack空间确实小了。
解决方式:由于JVM没有提供参数设置总的stack空间大小,但可以设置单个线程栈的大小;而系统的用户空间一共是3G,除了Text/Data/BSS /MemoryMapping几个段之外,Heap和Stack空间的总量有限,是此消彼长的。因此遇到这个错误,可以通过两个途径解决:
- 通过
-Xss
启动参数减少单个线程栈大小,这样便能开更多线程(当然不能太小,太小会出现StackOverflowError)。 - 通过
-Xms
和-Xmx
两参数减少Heap大小,将内存让给Stack(前提是保证Heap空间够用)。
情况二:
java.lang.StackOverflowError
原因:内存溢出错误的一种,即线程栈的溢出,要么是方法调用层次过多,比如存在无限递归调用。要么是线程栈太小。
解决方式:优化程序设计,减少方法调用层次;调整-Xss参数增加线程栈大小。
注意:如果是递归无限调用的话,经常会出现这种栈异常,有递归时注意一下。