JVM-内存区域划分

1.JVM内存区域的划分

根据《Java虚拟机规范》的规定,运行时数据区通常包括这几个部分:程序计数器(Program Counter Register)、Java栈(VM Stack)、本地方法栈(Native Method Stack)、方法区(Method Area)、堆(Heap)。

2.各个区域的职责

2.1程序计数器(Program Counter Register)

与CPU上的程序计数器类似,JVM的程序计数器用来指示JVM下一步应该去执行什么指令。

每个线程都拥有自己独立的程序计数器。

当线程正在执行一个Java方法时,PC计数器记录的是正在执行的虚拟机字节码的地址;当线程正在执行的一个Native方法时,PC计数器则为空(Undefined)。

2.2虚拟机栈(Java Vitual Machine Stack)

虚拟机栈,生命周期与线程相同,是Java方法执行的内存模型。

每个方法(不包含native方法)执行的同时都会创建一个栈帧结构,方法执行过程,对应着虚拟机栈的入栈到出栈的过程。

2.2.1栈帧结构

2.2.1.1局部变量表

每个栈帧包含一个称为局部变量的变量数组。帧的局部变量数组的长度在编译时确定,并以类或接口的二进制表示以及与该帧相关的方法的代码提供。

2.2.1.2操作数栈

每个帧包含称为其操作数栈的后进先出(LIFO)堆栈。帧的操作数栈的最大深度在编译时确定,并与用于与帧相关的方法的代码一起提供。

类似于数据结构中表达式求值的栈作用。

2.2.1.3动态链接

方法的class文件代码引用要调用的方法和通过符号引用访问的变量。动态链接将这些符号方法引用转换为具体的方法引用,根据需要加载类以解析尚未定义的符号,并将变量访问转换为与这些变量的运行时位置相关联的存储结构中的适当偏移。

2.2.1.4方法返回

正常退出

返回入口,并返回本函数的返回值。

异常退出

不拥有返回值,抛出异常。

2.2.1.5额外附加信息,虚拟机规范没有明确规定,由具体虚拟机实现。

2.2.2异常

  • StackOverFlowError:当线程请求栈深度超出虚拟机栈所允许的深度时抛出
  • OutOfMemoryError:当Java虚拟机动态扩展到无法申请足够内存时抛出

2.3本地方法栈

本地方法栈则为虚拟机使用到的Native方法提供内存空间,而前面讲的虚拟机栈式为Java方法提供内存空间。有些虚拟机的实现直接把本地方法栈和虚拟机栈合二为一,比如非常典型的Sun HotSpot虚拟机。

异常(Exception):

Java虚拟机规范规定该区域可抛出StackOverFlowError和OutOfMemoryError。

2.4堆

Java堆,是Java虚拟机管理的最大的一块内存,也是GC的主战场,里面存放的是几乎所有的对象实例和数组数据。JIT编译器有栈上分配、标量替换等优化技术的实现导致部分对象实例数据不存在Java堆,而是栈内存。

异常(Exception):

Java虚拟机规范规定该区域可抛出OutOfMemoryError。

2.5方法区

方法区主要存放的是已被虚拟机加载的类信息、常量、静态变量、编译器编译后的代码等数据。GC在该区域出现的比较少。

2.5.1运行时常量池

运行时常量池也是方法区的一部分。它包含几种常量,从编译时已知的数字字面量到必须在运行时解析的方法和字段引用。

异常(Exception):

Java虚拟机规范规定该区域可抛出OutOfMemoryError。

3.参考资料

The Structure of the Java Virtual Machine

Jvm内存模型

打赏