5. OOM异常类型
5.1 Java heap space
java.lang.OutOfMemoryError: Java heap space
异常展示
/**
* 设置堆初始大小 和 最大大小
* -Xms10m -Xmx10m
* -XX:InitialHeapSize=10m -XX:MaxHeapSize=10m
*/
public class HeapDemo1 {
private static byte[] bytes = new byte[12*1024*1024];
public static void main(String[] args) {
// System.out.println(HeapDemo.bytes);
}
}
5.2 stackOverflow
java.lang.StackOverflowError
代码演示
/**
* -Xss10k
*/
public class StackDemo {
public static void main(String[] args) {
stackOverFlow();
}
// 递归调用
public static void stackOverFlow(){
stackOverFlow();
}
}
5.3 GC overhead limit exceeded
GC回收时间过长,会报
java.lang.OutOfMemoryError: GC overhead limit exceeded
异常;通俗理解就是说,如果一直进行GC但是没有回收多少内存,这个时候就会报这个异常
/**
* -Xms10m -Xmx10m
* -XX:PrintGcDetails
*-XX:MaxDirectMemorySize=5M
* GC回收时间长出发 OOM
*/
public class GcDemo {
public static void main(String[] args) {
List<String> stringList = new ArrayList<>();
int i = 0;
try {
//一直 add 数据
while (true){
// list 中新增数据为 String数据会在常量池,为了更快实现效果,设置本地内存大小
// -XX:MaxDirectMemorySize=5M
stringList.add(String.valueOf(++i).intern());
}
} catch (Throwable e) {
System.out.println(i);
e.printStackTrace();
}
}
}
5.4 Direct buffer memory
java.lang.OutOfMemoryError: Direct buffer memory
本地内存不够会报这个异常
/**
* 设置本地内存大小:-XX:MaxDirectMemorySize=5m
*/
public class BufferMemoryDemo {
public static void main(String[] args) {
System.out.println(VM.maxDirectMemory()/(double)1024/1024 +"MB");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
// ByteBuffer buffer = ByteBuffer.allocate(10 * 1024 * 1024);
// 分配本地内存, 本地内存不够 ,报错:java.lang.OutOfMemoryError: Direct buffer memory
ByteBuffer buffer = ByteBuffer.allocateDirect(10 * 1024 * 1024);
}
}
5.5 unable to create native Thread
高并发的应用场景中,可能会报出这个错误
unable to create native Thread
/**
* java.lang.OutOfMemoryError: unable to create new native thread
*/
public class ThreadMaxDemo {
public static void main(String[] args) {
// 本地可编写java源文件,去掉 package 包引用
for (int i = 0; ; i++) {
//一直新增 线程
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
}
注意:最好在虚拟机或者服务器上执行,本机可能会电脑卡顿
-
本地可编写java源文件,去掉 package 包引用
-
上传文件到虚拟机或服务器(须装jdk环境),编译源文件,
javac ThreadMaxDemo.java
,生成.class文件 -
运行class 文件, 执行
java ThreadMaxDemo.class
执行结果: