jvm 的out of memory常见类型及演示demo

    说起jvm就避免不了谈及jvm的内存划分。本文主要说一下hotspot运行时数据区域的的划分和常见的Out Of Memory演示demo。本文主旨在记录自己所学知识,同时方便后续查阅,有不足支出请大家指正。

一、hotspot的内存分区

hotspot的jvm运行时数据区域分为堆、栈、方法区(永久代)、程序计数器。

二、各分区的简要介绍

堆又细分为新生代和老年代。新生代又细分为Eden空间、from survivor空间和to survivor空间,其中Eden:survivor=8:1(默认情况)。可以通过-Xms10m和-Xmx20m来设置堆内存的大小。可以通过-XX:NewSize=10m和-XX:MaxNewSize=20m来设置新生代的大小。可以通过-XX:NewRatio=2(老年代是新生代大小的2倍)来设置老年代和新生代的比例,通过-XX:SurvivorRatio=8来设置Eden和survivor的比例。

堆上会抛Out Of Memory异常的demo

//package OutOfMemory;//注释掉

import java.util.ArrayList;

public class JavaHeapSpace {
    public static void main(String args[]){
        ArrayList arryList=new ArrayList();
        int i=0;
        while(true){
            i++;
            arryList.add(String.valueOf(i));
            if(i<0){
              break;
            }
        }
    }

}

其中包名我是注释掉的,因为我是在cmd进行编译和运行。若加上包名会报找不到主函数的异常,执行结果如下:

jvm 的out of memory常见类型及演示demo

栈又分成虚拟机栈和本地方法栈,可以通过-xss10m来设置线程栈的大小

栈异常之*Error 

//package OutOfMemory;//注释掉

import java.util.ArrayList;

public class JavaHeapSpace {
    public static void main(String args[]){
        ArrayList arryList=new ArrayList();
        int i=0;
        while(true){
            i++;
            arryList.add(String.valueOf(i));
            if(i<0){
              break;
            }
        }
    }

}

jvm 的out of memory常见类型及演示demo

栈异常之 unable to create native thread

package OutOfMemory;

public class ThreadStack {
    public void notStop(){
        while(true){

    }
    }
    public void threadStack(){
        while(true) {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    notStop();
                }
            });
            t.start();
        }
    }
    public static void main(String args[]){
        ThreadStack threadStack=new ThreadStack();
        threadStack.threadStack();

    }

}

jvm 的out of memory常见类型及演示demo

以上是常见的两种栈溢出异常。

方法区(永久代)

方法区(永久代)可以通过调整-XX:PermSize=10m和-XX:MaxPermSize=10m来设置方法区的大小,不过此区域有最小默认值。即想调整方法区比较小时,不一定生效。如下案例代码在jdk1.6下是可以出现异常的,在jdk1.7及以上不会出现异常

//package OutOfMemory;

import java.util.ArrayList;

public class PermGenSpace {
    public static void main (String args[]){
        ArrayList arryList=new ArrayList();
        int i=0;
        while(true){
            arryList.add(String.valueOf(++i).intern());
        }
    }
}

jvm 的out of memory常见类型及演示demo

最后一个是程序计数器,此区域是不会出现OutOfMemoryError的。