OutOFMemoryError

版权声明:本文为博主原创文章,未经博主允许不得转载。http://www.cnblogs.com/jokermo/

注:本文属于《深入理解java虚拟机》读书笔记,想详细了解请自行看书。

1.Java堆溢出

Java堆用于存储对象实例,只要不断创建对象,并且保证GC Roots到对象之间有可到达路径来避免垃圾回收机制清除这些对象,那么对象数量达到容量限制后就会产生内存溢出异常。

import java.util.ArrayList;
import java.util.List;

/**
 * VM Args:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
 * create by jokermo
 **/
public class HeapOOM {
    static class OOMObject{}
    public static void main(String[] args){
        List<OOMObject> list = new ArrayList<OOMObject>();
        while (true){
            list.add(new OOMObject());
        }
    }
}
运行结果,其中java.lang.OutOfMemoryError:java heap space表示java堆内存溢出异常

 


-Xms20m -Xmx20m:表示java堆大小为20M且不可扩展
解决Java堆异常:
  • 首先通过内存映像分析工具(如Eclipse Memory Analyzer)对Dump出的堆存储快照进行分析,主要是确认内存中的对象是否必须的,也就是确定属于内存泄露(Momory Leak)还是内存溢出(Memory Overflow)
  • 如果是内存泄露,可进一步通过工具查看泄露对象到GC Roots的引用链,掌握了泄露对象的类型信息及GC Roots引用链信息,就可以比较准确的定位出泄露代码的位置。
  • 如果是内存溢出(内存对象还必须活着)
  1. 查看虚拟机的堆参数(-Xmx 和-Xms),与机器物理内存对比是否还可以调大。
  2. 从代码上检查是否存在某些对象生命周期过长,持有状态过长的情况,尝试减少程序运行期内存的消耗。

2.虚拟机栈和本地方法栈溢出

虚拟机与本地方法区的两种异常:

  • 如果线程请求的栈深度大于虚拟机所运行的最大深度,将抛出StackOverflowError异常
  • 如果虚拟机在扩展栈时无法申请到足够的内存空间,将抛出OutOfMemoryError异常

抛出StackOverflowError异常,异常出现时输出的栈深度相应缩小示例:

  • 使用-XSS参数减少栈内存容量。
  • 定义大量的本地变量,增大此方法帧中本地变量表的长度。
/**
 * VM Args:-Xss128k
 * create by jokermo
 **/
public class JavaVMStackSOF {
    private int stackLength = 1;
    public void stackLeak(){
        stackLength++;
        stackLeak();
    }
    public static void main(String[] args){
        JavaVMStackSOF javaVMStackSOF = new JavaVMStackSOF();
        try {
            javaVMStackSOF.stackLeak();
        }catch (Throwable e){
            System.out.print("stack Length:" + javaVMStackSOF.stackLength);
            throw e;
        }
    }
}

结果:

 

结果显示:在单线程情况下,无论是由于栈帧太大还是虚拟机栈容量太小,当内存无法分配的时候,虚拟机抛出的都是StackOverflowError异常。

 

在多线程情况下,通过不断创建线程可以产生内存溢出异常。

解决方法:

  • 通过减少线程数或者更换64位的虚拟机。
  • 若无法满足上面条件,可以通过减小最大堆和减少栈容量来获取更多线程。

 3.方法区和运行时常量池溢出

运行时常量池是方法区的一部分,方法区用于存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。

异常信息为permGen space

4.本机直接内存溢出

 

posted @ 2018-05-02 16:40  jokermo  阅读(129)  评论(0编辑  收藏  举报