JVM基础总结03 - JVM进阶之OOM
一、谈谈对OOM的认识
1.java.lang.StackOverflowError
一个深度的加载或者递归调用可能会导致StackOverFlowError
public class StackOverflowDemo {
public static void main(String[] args) {
stackOverflow();
}
private static void stackOverflow() {
stackOverflow();
}
}
Exception in thread "main" java.lang.StackOverflowError
2.java.lang.OutOfMemoryError:Java heap space
大量对象把堆内存撑爆
public class JavaHeapSpaceDemo {
public static void main(String[] args) {
byte[] bytes = new byte[20 * 1024 * 1024];
}
}
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at season2.jvm.five.JavaHeapSpaceDemo.main(JavaHeapSpaceDemo.java:6)
3.java.lang.OutOfMemoryError:GC overhead limit exceeded
大量对象创建,导致GC回收不动,98%的时间用来做GC,并且回收了不到2%的内存
4.java.lang.OutOfMemoryError:Direct buffer memory
直接内存错误,在写NIO程序的时候,在直接内存开辟的空间小于直接内存,会报这个错误
public class DirectBufferMemoryDemo {
public static void main(String[] args) {
System.out.println("配置的maxDirectMemory" + (sun.misc.VM.maxDirectMemory() / (double)1024 / 1024) + "MB");
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(6 * 1024 * 1024);
}
}
5.java.lang.OutOfMemoryError:unable to create new native thread
高并发场景下,线程的创建超过限制,linux默认一个进程允许创建的最大线程是1024,使用ulimit -u查看
public class UnableCreateNewThreadDemo {
public static void main(String[] args) {
for (int i = 1; ; i++) {
System.out.println(i);
new Thread(() -> {
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}
6.java.lang.OutOfMemoryError:Metaspace
元空间存放了以下信息:
虚拟机加载的类信息
常量池
静态变量
即时编译后的代码
元空间默认大小21M,在元空间生成很多的静态类,当超过元空间大小时,会报OOM:MetaSpaceSize
public class MetaSpaceOOMDemo {
static class OOMTest{}
public static void main(String[] args) {
int i = 0;
try {
while (true) {
i++;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OOMTest.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
return methodProxy.invokeSuper(o, args);
}
});
enhancer.create();
}
} catch (Throwable e) {
System.out.println("多少次后产生异常:" + i);
e.printStackTrace();
}
}
}
多少次后产生异常:285
java.lang.OutOfMemoryError: Metaspace
-XX:+PrintFlagsInitial命令查看本机的初始化参数,-XX:MetaSpaceSize约为22M
其他:
一个线程两次start会报不合法的线程状态 IllegalThreadStateException