第二章(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 本机直接内存溢出


浙公网安备 33010602011771号