JMM内存模型

Java 内存区域

本篇是《深入理解Java虚拟机》的笔记,配合 The Java® Virtual Machine Specification 食用风味更佳

运行时数据区域

程序计数器:

当前线程所执行的字节码行号指示器,字节码解释器的工作就是改变程序计数器的值来选取吓一跳需要执行的字节码指令,分支循环,跳转,异常处理,线程恢复等等基础功能都需要依赖这个计数器来完成。
计数器的记录值:

如果执行的是Java方法,记录的是虚拟机字节码指令地址,如果是Native方法,计数器值为空(Undefined)

可能抛出的异常:

无,唯一一个运行时无异常的区域。

Java虚拟机栈

线程私有,生命周期与线程相同。
描述Java方法执行的内存模型。
每个方法在执行时都会创建一个栈桢StackFrame,用于存储 局部变量表,操作数栈,动态链接,方法出口等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈桢在虚拟机栈中入栈到出栈的过程。
通常意义上的 “栈” 指的就是Java 虚拟机栈

可能抛出的异常:

  • StackOverFlow
    • 如果线程请求的栈深度大雨虚拟机栈所允许的深度,则抛出StackOverFlow异常
  • OutOfMemory
    • 如果虚拟机栈可以动态扩展,并且扩展时无法申请到足够的内存,就会抛出OutOfMemory异常。

本地方法栈

与虚拟机栈作用类似,区别是 虚拟机栈为Java 虚拟机执行 Java方法服务,本地方法栈为虚拟机使用到的 Native 方法服务。

JVM 并未规定本地方法栈中的语言,使用方式,数据结构做强制规定。具体虚拟机可以自己进行实现。

抛出的异常与虚拟机栈一样。

Java堆

Java堆是Java运行时共享数据区域,在JVM启动时创建。

该区域的作用是存放对象实例。

Java堆可分为 新生代和老年代,更细一点油 Eden空间,FromSurvivor 空间, To Survior 空间。,

从内存分配的角度来看 ,线程共享的Java堆中可能划分出多个线程私有的分配缓冲区,但是无论如何划分,都与存放的内容无关,存放的都是Java对象实例。 划分的目的是更快的回收或者分配。

根据Java虚拟机的规定,Java堆可以处于物理不连续的内存空间中,只要逻辑上是连续的即可。

方法区

线程共享内存区域。

存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。

别名— Non-Heap 非堆。HotSpot中方法区别名永久代,但是本质上两者不等价,只是HotSpot的实现把GC分代收集扩展到了方法取区。或者使用永久代来实现方法区。这样能够省去专门编写方法区GC的工作。 但是这是1.7的 JVM了 现在不知道是否已经发生了变化。

分享到:
0%