JVM 内存模型 - litter-fish/ReadSource GitHub Wiki

JVM 启动流程 c77a0ac84fe41feedc067432ac270146.png

JVM 基本结构图 ce2c61ea003fb1db9f3da28eeadf9036.jpeg

运行时数据区 76e4ac6c941408f7d4185a02dadad9e0.jpeg

JVM 的内存划分

存放局部变量 Java方法执行的内存模型:每个方法被调用的时候都会创建一个栈帧,用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程就对应着一个栈帧在虚拟机中从入栈到出栈的过程。

  • 线程私有,生命周期和线程相同
  • 栈由一系列帧组成(因此Java栈也叫做帧栈)
  • 帧保存一个方法的局部变量、操作数栈、常量池指针
  • 每一次方法调用创建一个帧,并压栈

栈帧中主要保存的数据:

  • 局部变量区:包括输入参数、输出参数及方法内的参数
  • 操作数栈:记录出栈、入栈的操作
  • 栈数据区:包括类文件及方法 栈数据区的作用 解析常量池里面的数据 方法执行完后处理方法返回,恢复调用现场 方法执行过程中抛出异常时的异常处理

307103d591696f2b3afce6bdfd0457f6.png

可能出现的异常情况

  • StackOverFlowError:如果线程请求的栈深度太深,超出了虚拟机所允许的深度
  • OOM:虚拟机栈可以动态扩展,如果扩展到无法申请足够的内存空间

存放实例变量,所有线程共享 堆的细分: f381d6333f58ac3da837510889e11543.jpeg

  • Perm:主要保存class,method,filed对象 遇到的异常:java.lang.OutOfMemoryError : PermGen space
  • Tenured: 保存生命周期比较长的对象
  • Young: Young可以再次划分为:Eden区和两个大小严格相同的Survivor区,其中Survivor区间中,某一时刻只有其中一个是被使用的,另外一个留做垃圾收集时复制对象用,在Young区间变满的时候,minor GC就会将存活的对象移到空闲的Survivor区间中,根据JVM的策略,在经过几次垃圾收集后,任然存活于Survivor的对象将被移动到Tenured区间。

方法区 被虚拟机加载的类信息、常量、静态常量等 程序计数器 每一个线程都拥有一个PC寄存器,用于指向下一条指令的地址 本地方法栈 用于管理本地方法的调用。 本地方法可以通过本地接口来访问虚拟机内部的运行时数据区, 同时也会出现:StackOverFlowError 和 OOM 异常

栈、堆、方法区交互 fccefa1716bb5f1287dd3f8ac26cf321.jpeg 5275bfcfaccf6c77c754b899807ef0eb.png