1、java.lang.StackOverflowError
- 在一个函数中递归调用就会产生这样的错误(栈溢出)
- 发生区域:java虚拟机栈或本地方法栈
1 2 3 4 5 6 7 8 9 | public class StackOverFlowErrorDemo { public static void main(String[] args) { stackOverFlowError(); } public static void stackOverFlowError(){ stackOverFlowError(); } } |
2、java.lang.OutOfMemoryError: Java heap space
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /** * -Xms10m -Xmx10m */ public class JavaHeapSpaceDemo { static class OOMObject{ } public static void main(String[] args) { List<OOMObject> list = new ArrayList<>(); while ( true ){ list.add( new OOMObject()); } } } |
3、java.lang.OutOfMemoryError: GC overhead limit exceeded
- GC回收时间过长,超过98%的时间用来做GC,并且回收了不到2%的堆内存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /** * -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m */ public class GCoverheadDemo { public static void main(String[] args) { int i = 0 ; List<String> list = new ArrayList<>(); while ( true ) { list.add(String.valueOf(++i).intern()); } } } |
4、java.lang.OutOfMemoryError: Direct buffer memory
原因:直接内存不足
![](https://img-blog.csdnimg.cn/20200611164150492.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTMzNzI5OTM=,size_16,color_FFFFFF,t_70)
1 2 3 4 5 6 7 8 9 10 11 | /** * -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m */ public class DirectBufferMemoryDemo { public static void main(String[] args) throws InterruptedException { System.out.println( "maxDirectMemory : " + sun.misc.VM.maxDirectMemory() / 1024 / 1024 + "MB" ); TimeUnit.SECONDS.sleep( 1 ); ByteBuffer byteBuffer = ByteBuffer.allocateDirect( 6 * 1024 * 1024 ); } } |
5、java.lang.OutOfMemoryError : unable to create new native thread
- 一个应用进程创建了多个线程,超过系统承载极限,Linux默认允许单个进程可以创建的线程数1024
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /** * 一个应用进程创建了多个线程,超过系统承载极限,Linux默认是1024 */ public class UnableCreateNewThreadDemo { public static void main(String[] args) { for ( int i = 0 ; ; i++) { new Thread(() -> { try { Thread.sleep(Integer.MAX_VALUE); } catch (InterruptedException e) { e.printStackTrace(); } }, String.valueOf(i)).start(); } } } |
linux系统下:
1 2 | ulimit -u --查看线程上限 cat /etc/security/limits.d/ 20 -nproc.conf |
6、java.lang.OutOfMemoryError: Metaspace
java8使用Metaspace代替永久代,与永久代最大的区别是:元空间并不在虚拟机内存中,而是使用本地内存。
永久代(java8使用Metaspace)存放的信息:
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 | /** * 不断生成类往元空间推,类占据的空间总是会超过Metaspace的大小 * -XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=8m */ 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(); } } |