91名师指路-头部
91名师指路

面试题(七)请你谈谈对OOM的认识

由于某些原因,现在不支持支付宝支付,如需要购买源码请加博主微信进行购买,微信号:13248254750

常见的OOM异常:

(1)Java.lang.StackOverflowError

(2)Java.lang.OutOfMemoryError:Java heap space

(3)Java.lang.OutOfMemeoryError:GC overhead limit exceeded

(4)Java.lang.OutOfMemeoryError:Direct buffer memory

(5)Java.lang.OutOfMemeoryError:unable to create new native thread

(6)Java.lang.OutOfMemeoryError:Metaspace


一:StackOverflowError异常演示。

package com.mszl.oom;

/**
* 功能:StackOverflowError 演示
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
public class StackOverflowErrorDemo {
    // 递归调用,深度加载
public static void main(String[] args) {
stackFlowError();
}

public static void stackFlowError(){
stackFlowError();
}


}

栈默认大小为:512k - 1024k。

执行结果

Exception in thread "main" java.lang.StackOverflowError
at com.mszl.oom.StackOverflowErrorDemo.stackFlowError(StackOverflowErrorDemo.java:15)
at com.mszl.oom.StackOverflowErrorDemo.stackFlowError(StackOverflowErrorDemo.java:15)
at com.mszl.oom.StackOverflowErrorDemo.stackFlowError(StackOverflowErrorDemo.java:15)
at com.mszl.oom.StackOverflowErrorDemo.stackFlowError(StackOverflowErrorDemo.java:15)


查下面的架构图可以得出:StackOverflowError和OutOfMemoryError都是属于Error错误。


二:OutOfMemoryError:Java heap space异常演示

package com.mszl.oom;

/**
* 功能:OutOfMemoryError:Java heap space演示
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
public class OutOfMemoryErrorDemo {

public static void main(String[] args) {
byte[] bt=new byte[30 * 1024 * 1024];
}


}
我们将eclipse的jvm参数设置为-Xms10m -Xmx10m

执行结果

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.mszl.oom.OutOfMemoryErrorDemo.main(OutOfMemoryErrorDemo.java:11)


三:GC overhead limit exceeded异常演示

package com.mszl.oom;

import java.util.ArrayList;
import java.util.List;

/**
* 功能:GC overhead limit exceeded 演示
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
public class GcOverHeadDemo {

public static void main(String[] args) throws Throwable {
int i=0;
List<String> list=new ArrayList<String>();
try{
while(true){
list.add(String.valueOf(i++).intern());
}
} catch(Exception e){
e.printStackTrace();
/*System.out.println(">>>>>>>>>>>>>>>>> " + i);
throw e;*/
}
}


}

在eclipse里面设置jvm参数

-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+UseParallelGC -XX:MaxDirectMemorySize=5m

注意:你可能执行的结果和我的不一样,这和jvm的参数和垃圾回收算法有关系。

执行结果

[Full GC (Ergonomics) [PSYoungGen: 2816K->2816K(3072K)] [ParOldGen: 6788K->6788K(6912K)] 9604K->9604K(9984K), [Metaspace: 1757K->1757K(4480K)], 0.0583665 secs] [Times: user=0.23 sys=0.00, real=0.06 secs] 
[Full GC (Ergonomics) [PSYoungGen: 2816K->2816K(3072K)] [ParOldGen: 6790K->6790K(6912K)] 9606K->9606K(9984K), [Metaspace: 1757K->1757K(4480K)], 0.0581287 secs] [Times: user=0.25 sys=0.00, real=0.06 secs]
Exception in thread "main" [Full GC (Ergonomics) java.lang.OutOfMemoryError: GC overhead limit exceeded
[PSYoungGen: 2816K->0K(3072K)] [ParOldGen: 6792K->460K(6912K)] 9608K->460K(9984K), [Metaspace: 1773K->1773K(4480K)], 0.0097761 secs] [Times: user=0.06 sys=0.00, real=0.01 secs]
at java.lang.Integer.toString(Integer.java:403)
at java.lang.String.valueOf(String.java:3099)
at com.mszl.oom.GcOverHeadDemo.main(GcOverHeadDemo.java:18)
Heap
PSYoungGen total 3072K, used 60K [0x044c0000, 0x04800000, 0x04800000)
eden space 2816K, 2% used [0x044c0000,0x044cf350,0x04780000)
from space 256K, 0% used [0x047c0000,0x047c0000,0x04800000)
to space 256K, 0% used [0x04780000,0x04780000,0x047c0000)
ParOldGen total 6912K, used 460K [0x03e00000, 0x044c0000, 0x044c0000)
object space 6912K, 6% used [0x03e00000,0x03e733d0,0x044c0000)
Metaspace used 1777K, capacity 2242K, committed 2368K, reserved 4480K

总结:GC回收时间过长时会抛出OutOfMemoryError,过长的定义是:超过98%的时间用来做GC并且回收了不到2%的堆内存,连续多次GC都只回收了不到2%的极端情况下才会抛出。假如不抛出GC overhead limit exceeded 错误会发生什么情况呢?那就是GC清理的这么点内存很快会再次填满,迫使GC再次执行,这样就形成恶性循环,CPU使用率一直是100%,而GC却没有任何成果。



2019-12-11 16:39:53     阅读(1155)

名师出品,必属精品    https://www.91mszl.com

联系博主    
用户登录遮罩层
x

账号登录

91名师指路-底部