前言
看本文之前,可以先了解下什么是异常
12-异常
一、StackOverflowError
栈溢出,其他关于栈的介绍,可以参考 1-JVM体系结构概述
直接上代码看
public class Test02 {public static void main(String[] args) {System.out.println("sssss");fun1();System.out.println("uuuuuu");}public static void fun1(){fun1();}}// Exception in thread "main" java.lang.StackOverflowError
以上代码递归调用自己,最终导致栈溢出,这是error级别错误,不是Exception
二、OutOfMemoryError: Java heap space
new一个大对象导致堆内存溢出
堆占用太多也会触发GC,参考 4-制造GC/Full GC
public class Test01 {public static void main(String[] args) throws InterruptedException {byte[] bytes = new byte[10 * 1024 * 1024];}}抛出异常Exception in thread "main" java.lang.OutOfMemoryError: Java heap spaceat Demo03.Test01.main(Test01.java:17)
三、OutOfMemoryError: GC overhead limit

综上所述,用了98%的时间去GC却只回收了2%的堆内存,连续多次GC都只回收不到2%的内存的 极端情况下,会报错 GC overhead limit。
代码示例如下,数次GC,但是每次GC回收的内存小于2%,就会报错。
先使用如下配置,调小自己的堆大小
-Xms1m -Xmx2m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m
/*** @description: 模拟 java.lang.OutOfMemoryError: GC overhead limit exceeded* -Xms10m -Xmx20m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m* MaxDirectMemorySize:直接内存大小,因为本机内存太大,所以设置的小一点** @Author: wangchao* @Date: 2021/7/31*/public class GCOverheadDemo {public static void main(String[] args) {int i = 0;ArrayList<Object> list = new ArrayList<>();try {while (true){// TODO 记得关注 https://www.runoob.com/java/java-string-intern.htmllist.add(String.valueOf(++i).intern());}}catch (Throwable e){System.out.println("***************i:"+i);e.printStackTrace();throw e;}}}// 输出java.lang.OutOfMemoryError: GC overhead limit exceeded
四、OutOfMemoryError: Direct buffer memory
// -Xms10m -Xmx20m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5mpublic class DirectBufferMemoryDemo {public static void main(String[] args) {// 默认是本机的1/4 ,为了测试,我们将直接内存调小 -XX:MaxDirectMemorySize=5mSystem.out.println("配置的maxDirectMemory:"+(VM.maxDirectMemory()/(double)1024/1024)+"MB");ByteBuffer byteBuffer = ByteBuffer.allocateDirect(6 * 1024 * 1024);}}
五、OutOfMemoryError: unable to create new native thread
public class UnableCreateNewThreadDemo {public static void main(String[] args) {for (int i = 0; i < 10000; i++) {new Thread(() -> {System.out.println(Thread.currentThread().getName() + "start");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {e.printStackTrace();}}, "" + i).start();}}}报错:Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native threadat java.lang.Thread.start0(Native Method)at java.lang.Thread.start(Thread.java:717)at com.supkingx.base.l_jvm.gc.oom.UnableCreateNewThreadDemo.main(UnableCreateNewThreadDemo.java:18)
六、OutOfMemoryError: Metaspace
// -XX:MetaspaceSize=5m -XX:MaxMetaspaceSize=20mpublic 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() {@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {return methodProxy.invokeSuper(o, objects);}});Object o = enhancer.create();System.out.println("创建类:" + o);}} catch (Throwable e) {System.out.println("多少次后发生了异常:" + i);e.printStackTrace();}}}报错Caused by: java.lang.OutOfMemoryError: Metaspaceat java.lang.ClassLoader.defineClass1(Native Method)at java.lang.ClassLoader.defineClass(ClassLoader.java:756)... 14 more
报错原因如下
即 使用Enhancer创建数个代理类挤爆了MetaSpace
