java-异常错误演示

常遇到的JVM错误,知道出错原因并能演示,后边才能想办法解决它。

堆空间不足异常

jvm参数指定最大堆内存为10M,再加载10M的byte[]数组就会空间不足而出错。

1
2
3
4
5
6
7
8
9
//java.lang.OutOfMemoryError: Java heap space
// -Xmx10M
public static void main(String[] args) throws IOException {

Test test = new Test();
//10M的byte[]数组
byte[] bytes = new byte[1024*1024*10];
System.out.println(bytes);
}

栈溢出异常

虚拟机栈,给每个线程分配的空间默认是1M,可通过参数-Xss1M设置;
java方法运行时,jvm会为每个线程分配一个jvm栈,每个方法有自己的栈帧(栈帧里记录了局部变量和方法出口等信息),
栈长度超过jvm允许的最大深度的就会报StackOverflowError异常。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//java.lang.StackOverflowError
public class T2_stackoverflow {

public static void main(String[] args) {
T2_stackoverflow t2_stackoverflow = new T2_stackoverflow();
t2_stackoverflow.execute();
}

//一个方法内一直递归导致找不到出口;就会报stackoverflowerror
public void execute(){
execute();
}

}

方法区异常

jvm方法区记录着被jvm所加载的类信息。
所以当类加载器加载过多类时,就会异常报错

依赖asm wget https://repo1.maven.org/maven2/asm/asm/3.1/asm-3.1.jar

vim T3_oom.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.ClassWriter;

public class T3_oom extends ClassLoader{
static MyClassLoader myClassLoader = new MyClassLoader();

//1.7 -Xss1M -Xmx10M -XX:MaxPermSize=10M -XX:+PrintGC

// java.lang.OutOfMemoryError: Metaspace
//1.8 -Xss1M -Xmx10M -XX:MaxMetaspaceSize=10m -XX:+PrintGC
public static void main(String[] args) throws ClassNotFoundException {
Class clazz = myClassLoader.findClass("ClassA");
System.out.println(clazz);
}
}

/**
* 定义类加载器
* @author SPC-00D
*
*/
class MyClassLoader extends ClassLoader{

@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
MyClassWriter classWriter = new MyClassWriter(0);
classWriter.visit(name);
byte[] bytes = classWriter.toByteArray();
//加载字节码
return super.defineClass(name, bytes,0, bytes.length);
}

}

/**
* 基于asm生成字节码
* @author SPC-00D
*
*/
class MyClassWriter extends ClassWriter implements Opcodes{
public MyClassWriter(int flag) {
super(flag);
}

public void visit(String name) {
super.visit(V1_6, ACC_PUBLIC, name, null, "java/lang/Object", null);
}
}

编译 javac -cp asm-3.1.jar T3_oom.java
运行 java -cp asm-3.1.jar:. T3_oom

String字面量

1
2
3
4
5
6
7
8
9
10
11
public class StringOomMock {
static String base = "string";
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
for (int i=0;i< Integer.MAX_VALUE;i++){
String str = base + base;
base = str;
list.add(str.intern());
}
}
}