第二章(3)实战: OutOfMemoryError异常

先看几个JVM参数:

  1. -Xmx  设置应用程序(不是JVM)内存可用大小 ( 如果程序要花很大内存的话,可以修改缺省配置,但是不能超过机器的内存),即最大可用Heap的大小

  2. -Xms  设置初始Heap的大小 (设置这个值启动性能会提高,也会受到机器内存的限制和最大Heap的限制)

  很多情况下,一般-Xmx和-Xms 大小设置成一样大,因为不一样的话,在程序内存变化的情况下,每次垃圾回收后,都会重新分配内存。

  3. -Xss 规定了每个线程堆栈的大小。一般情况下256K是足够了。影响了此进程中并发线程数大小。

2.4.1 Java堆溢出

package outofmemory;

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

public class OutOfMemoryTest {
    static class OOMObject {
    }

    public static void main(String[] args) {
        List<OOMObject> list = new ArrayList<>();

        int i = 0;
        while(true) {
            list.add(new OOMObject());
            System.out.println(i++);
        }
    }
}

  

2.4.2 虚拟机栈和本地方法栈溢出

  

package vmstacksof;

public class JavaVMStackSOF {
    private int stackLenght = 1;

    public void stackLeak() {
        stackLenght++;
        stackLeak();
    }

    public static void main(String[] args) {
        JavaVMStackSOF oom = new JavaVMStackSOF();

        try {
            oom.stackLeak();
        } catch (Throwable e) {
            System.out.println("stack length:" + oom.stackLenght);

            throw e;
        }
    }
}

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

 String::intern() :  是一个本地方法。new String都是在堆上创建字符串对象。当调用 intern() 方法时,编译器会将字符串添加到常量池中(stringTable维护),并返回指向该常量的引用。

String a5 = new String("A") + new String("A");//只在堆上创建对象
a5.intern();//在常量池上创建引用
String a6 = "AA";//此时不会再在常量池上创建常量AA,而是将a5的引用返回给a6
System.out.println(a5 == a6); //true

Java 8里, 字符串常量池是在堆中,而不像以前的JDK那样,在方法区。

2.4.4 本机直接内存溢出

 

原文地址:https://www.cnblogs.com/liufei1983/p/13642338.html