一、OOM for Heap (java.lang.OutOfMemoryError: Java heap space) 分析
此OOM是由于JVM中heap的最大值大于程序运行期间最大可用内存大小,如果程序运行需要占用更多的内存,超出了这个设置值,就会抛出OutOfMemory异常。
- 解决思路
- 将设置heap的最大值调高即可,即-Xmx的值调大。参数样例为:-Xmx2G。
二、OOM for StackOverflowError (Exception in thread “main” java.lang.StackOverflowError)
- 如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。
- 如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。
- 解决思路
- 检查程序是否有深度递归,或者根据-Xss 是指设定每个线程的堆栈大小。
三、OOM for Perm (java.lang.OutOfMemoryError: PermGen space)
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中。
由于JVM在默认的情况下,Perm默认为64M,而很多程序需要大量的Perm区内 存,尤其使用到像Spring等框架的时候,由于需要使用到动态生成类,而这些类不能被GC自动释放,所以导致OutOfMemoryError: PermGen space异常。
- 解决思路
- 增大JVM的 -XX:MaxPermSize 启动参数,就可以解决这个问题。
四、OOM for GC (java.lang.OutOfMemoryError: GC overhead limit exceeded)
此OOM是由于JVM在GC时,对象过多,导致内存溢出,建议调整GC的策略,在一定比例下开始GC而不要使用默认的策略,或者将新代和老代设置合适的大小。
- 解决思路
- 改变GC策略,在老代80%时就是开始GC,并且将-XX:SurvivorRatio(默认-XX:SurvivorRatio=8,定义了新生代中Eden区域和Survivor区域的比例)和-XX:NewRatio(默认-XX:NewRatio=4,定义了新生代和老年代的比例)设置的更合理。
五、OOM for native thread created (java.lang.OutOfMemoryError: unable to create new native thread)
这个异常问题本质原因是我们创建了太多的线程,而能创建的线程数是有限制的,导致了异常的发生。
- 解决思路
- 如果JVM内存调的过大或者可利用率小于20%,可以建议将heap及perm的最大值下调,并将线程栈调小,即-Xss调小,如:-Xss128k。
六、OOM for allocate huge array (Exception in thread “main”: java.lang.OutOfMemoryError: Requested array size exceeds VM limit)
此类信息表明应用程序试图分配一个大于堆大小的数组。例如,如果应用程序new一个数组对象,大小为512M,但是最大堆大小为256M,因此OutOfMemoryError会抛出,因为数组的大小超过虚拟机的限制。
- 解决思路
- 首先检查heap的-Xmx是不是设置的过小,如果太小就调大。
- 如果heap的-Xmx已经足够大,那么请检查应用程序是不是存在bug,例如:应用程序可能在计算数组的大小时,存在算法错误,导致数组的size很大,从而导致巨大的数组被分配。
七、OOM for small swap (Exception in thread “main”: java.lang.OutOfMemoryError: request bytes for . Out of swap space? )
抛出这类错误,是由于从native堆中分配内存失败,并且堆内存可能接近耗尽。
- 解决思路
- 检查是否有其他进程在消耗大量的内存,从而导致当前的JVM内存不够分配。
八、OOM for exhausted native memory (java.lang.OutOfMemoryErr java.io.FileInputStream.readBytes(Native Method))
需要考虑问题的发生是由于Native memory被耗尽导致的。
- 解决思路
- 从根本上来说,解决此问题的方法应该通过检测发生问题时的环境下,native memory为什么被占用或者说为什么native memory越来越小,从而去解决引起Native memory减小的问题。