Java虚拟机:实战OutOfMemoryError异常
程序员文章站
2022-03-24 09:15:49
...
在Java虚拟机规范的描述中,除了程序计数器外,虚拟机内存的其它几个运行时数据区域都有发生OutOfMemoryError(OOM)
一、Java堆溢出
/**
* @author: hs
* @Date: 2019/12/11 10:25
* @Description:
* -Xms30m -Xmx30m -XX:+PrintGCDetails -XX:SurvivorRatio=8
* -XX:+HeapDumpOnOutOfMemoryError
*/
public class HeapOOM {
static class OOMObject{
}
public static void main(String[] args) {
List<OOMObject> list = new ArrayList<>();
while (true){
list.add(new OOMObject());
}
}
}
将堆的最小值参数-Xms和最大值参数-Xmx设置为一样即可避免堆自动扩展,通过参数-XX:+HeapDumpOnOutOfMemoryError可以让虚拟机在出现内存溢出异常时Dump出当前的内存堆转储快照以便事后进行分析。
如图:
从当前堆快照分析如图:
线程0xfed12730中list存放大量对象,重点是确认内存中的对象是否是必要的,也就是要先分清到底是内存泄漏还是内存溢出。
二、Java虚拟机栈和本地方法栈溢出
/**
* @author: hs
* @Date: 2019/12/11 14:56
* @Description:
* VM args: -Xss128k
*/
public class JVMStackSOF {
private int stackLength = 1;
public void stackLeak() {
stackLength++;
stackLeak();
}
public static void main(String[] args) {
JVMStackSOF stackSOF = new JVMStackSOF();
try {
stackSOF.stackLeak();
} catch (Exception e) {
System.out.println("length:"+stackSOF.stackLength);
throw e;
}
}
}
结果如图:
由于在Hotspot虚拟机中并不区分虚拟机栈和本地方法栈,因此对于HotSpot来说,-Xoss参数虽然存在,但实际是无效的。栈容量只有-Xss来设定。
关于虚拟机栈和本地方法栈在JVM规范中描述了两种异常:1.如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出*Error。2.如果虚拟机在扩展栈时无法申请足够的内存空间,则抛出OutOfMemoryError异常。
上一篇: 栈溢出攻击和shellcode
推荐阅读
-
Java虚拟机内存结构及编码实战
-
Java虚拟机三:OutOfMemoryError异常分析
-
深入理解Java虚拟机-Java内存区域与内存溢出异常(二)
-
带你手撕Java虚拟机栈(手把手实战)
-
模拟实战排查堆内存溢出(java.lang.OutOfMemoryError: Java heap space)问题
-
Java虚拟机内存模型与内存溢出异常
-
《深入理解java虚拟机》一 java内存区域与内存溢出异常
-
荐 Java虚拟机之Java内存区域与内存溢出异常
-
【JVM系列1】深入分析Java虚拟机堆和栈及OutOfMemory异常产生原因
-
深入理解Java虚拟机02--Java内存区域与内存溢出异常