Java8出现OOM测试

一、oom设计

private static void test(){
    int i=0;
    List<Object> list = new ArrayList<>();
    while(true){
        System.out.println(i++);
        list.add(new Object());
    }
}

写了如上方法,在main()方法中调用后,发现虽然堆区满了,但是也并没有出现oom,查阅发现java8因为Metaspace,所以并不是堆区满了就出现oom,所以配置如下参数:-Xmx56m -XX:MaxMetaspaceSize=128m  设置最大堆区为56m,设置最大Metaspace为128m,运行程序后,抛出了oom。

二、原因总结

1.JDK8 HotSpot JVM 移除了永久代(方法区),使用本地内存来存储类元数据信息并称之为:元空间(Metaspace),如下图所示:

 

2.java8中metaspace总结:

a.移除了PermGen 空间

b.大部分类元数据(Metaspace )都在本地内存中分配。

默认情况下,类元数据只受可用的本地内存限制

新参数(MaxMetaspaceSize)用于限制本地内存分配给类元数据的大小。如果没有指定这个参数,元空间会在运行时根据需要动态调整(意思是如果不设置MaxMetaspaceSize,则一直可能会占用完所有的物理内存,而物理内存占用过高,可能会被操作系统kill掉)。

 

三、方法区和永久代

1.方法区是所有线程共享的,主要用于存储类的信息、常量池、方法数据、方法代码等。通常又叫“非堆”。

2.PermGen(永久代)

对于 “java.lang.OutOfMemoryError: PermGen space “这个异常。这里的 “PermGen space”其实指的就是方法区。

3.区别和联系

方法区是 JVM 的规范,而“PermGen space”后者则是 JVM 规范的一种实现,而且只有 HotSpot 才有 “PermGen space”,而对于其他类型的虚拟机则没有。

发表评论

邮箱地址不会被公开。 必填项已用*标注