JVM的内存结构
jdk8 jvm说明根据oracle官方文档的描述,可以总结JVM运行时内存的划分
Java虚拟机栈
线程私有。每个jvm线程都会创建他的线程栈,线程的每次方法执行都会创建一个栈帧,栈帧存储局部变量、操作栈、动态链接、返回地址等。每次方法的执行相当于入栈出栈的过程。Java虚拟机栈可能出现的StackOverflowError、OutOfMemoryError。
程序计数器
当前线程所执行的字节码行号指示器。可以理解为再多线程环境下,线程的运行受cpu调度的不确定性,线程需要记录当前执行的指令位置,以便cpu调度唤醒时能够恢复到正确的执行位置。唯一一个不会出现OOM的内存区域。
本地方法栈
即JVM提供的native方法服务。
堆
对象创建的地方,占用jvm内存最大块。GC回收也主要在这里进行。同时按照实现,堆按年代分为年轻代、老年代、永久代(Metaspace)。年轻代具体还可分为Eden、From survivor、To Survivor。
方法区
线程共享,运行时常量池存储类信息,常量,静态变量,即编译器编译完的代码数据
OOM的场景
- StackOverflowError,最常见出现的场景,递归
public class SOFDemo {
public static void main(String[] args) {
loop();
}
private static void loop(){
loop();
}
}
Exception in thread "main" java.lang.StackOverflowError
OOM
public class OOMTest {
/**
* VM Args: -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
*/
public static void main(String[] args) {
List<byte[]> list = new ArrayList<>();
int i = 0;
while (true) {
list.add(new byte[5 * 1024 * 1024]);
System.out.println("分配次数:" + (++i));
}
}
}
分配次数:1
分配次数:2
分配次数:3
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid52924.hprof ...
Heap dump file created [16950087 bytes in 0.018 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.ognice.demo.OOMTest.main(OOMTest.java:20)
本文由博客一文多发平台 OpenWrite 发布!