谈谈你对OOM的认识
java.lang.StackOverflowError
public class StackOverflowErrorDemo {
public static void main(String[] args) {
stackOverflowError();
}
private static void stackOverflowError() {
stackOverflowError();
}
}
java.lang.OutofMemoryError: Java heap space
public static void main(String[] args) {
byte[] bytes = new byte[80 * 1024 * 1024];
}
java.lang.OutofMemoryError: GC overhead limit exceeded
JVM参数配置演示
Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m
GC回收时间过长时会抛出0utofMemroyError。过长的定义是,超过98%的时间用来做GC并且回收了不到2%的堆内存
连续多次GC 都只回收了不到2%的极端情况下才会抛出。假如不抛出 GC overhead limit 错误会发生什么情况呢?
那就是GC清理的这么点内存很快会再次填满,追使GC再次执行,这样就形成恶性循环,CPU使用率一直是100%,而GC却没有任何成果
public class GCOverheadDemo {
public static void main(String[] args) {
int i = 0;
List<String> list = new ArrayList<>();
try {
while (true){
list.add(String.valueOf(++i).intern());
}
}catch (Throwable e){
System.out.println("****************i: " + i);
e.printStackTrace();
throw e;
}
}
}
java.lang.OutOfMemoryError: Direct buffer memory
public class DirectBufferMemoryDemo {
public static void main(String[] args) {
System.out.println("配置的maxDirectMemory: " + (sun.misc.VM.maxDirectMemory() / (double) 1024 * 1024) + "MB");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
ByteBuffer bb = ByteBuffer.allocateDirect(6 * 1024 * 1024);
}
}
java.lang.OutOfMemoryError: unable to create new native thread
public class UnableCreateNewThreadDemo {
public static void main(String[] args) {
for (int i = 1; ; i++) {
System.out.println("*******************i: " + i);
new Thread(() -> {
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "" + i).start();
}
}
}
java.lang.OutofMemoryError: Metaspace