java虚拟机内存布局

java虚拟机运行时数据区:
这里写图片描述

java虚拟机在执行java程序时,将其所管理的内存,划分为若干个数据区域。其中包括:程序计数器,方法区,堆,虚拟机栈,本地方法栈。
下面一一进行解释。

1.程序计数器:当前线程执行字节码的行号指示器,保存cpu执行当前指令的地址,cpu从程序计数器中获得指令的执行地址,程序计数器便自动加1或者根据转移指针得到下一条指令的地址。

<1>在多线程任务调度中,cpu轮流执行每个任务,而这个任务可能未执行完cpu便转向执行另外一个任务时,就需要程序计数器来记录断点的位置,以保证下次cpu执行该任务时可以恢复到该位置。

<2>每个线程都有一个独立的线程计数器,之间互不影响。程序计数器是每个线程的“私有”内存。

2.java虚拟机栈

java虚拟机栈,描述的是java方法执行的内存模型。每个方法在执行时都会创建一个栈帧,来存储,局部变量表,操作数栈,动态连接和方法出口等信息。

<1>.局部变量表:存放编译期间可知的各种局部变量,包括基本数据类型,和其引用类型。局部变量表所需的内存空间在编译期间已经完成分配,当进入一个方法时,其对应的帧中对局部变量表分配的大小完全确定,在运行期间不会改变。

<2>.操作数栈
方法执行中进行算术运算或者是调用其他的方法进行参数传递的时候是通过操作数栈进行的。
在概念模型中,两个栈帧是相互独立的。但是大多数虚拟机的实现都会进行优化,令两个栈帧出现一部分重叠。令下面的部分操作数栈与上面的局部变量表重叠在一块,这样在方法调用的时候可以共用一部分数据,无需进行额外的参数复制传递。
<3>动态链接
指向运行时常量池的引用。在方法执行中可能会用类中的常量,所以必须有引用指向运行时常量池。
<4>方法出口
方法的返回地址,方法返回 之前调用其的位置。

java虚拟机栈,是线程私有的,它的生命周期与线程相同,

3.本地方法栈
本地方法栈与虚拟机栈实现类似,只不过本地方法栈存放与native方法有关的数据,而虚拟机栈存放与java方法有关的数据。

4.java堆

是线程共享的一块内存区域,在jvm启动时创建,所有对象实例和数组都要在堆上分配,是垃圾回收器管理的主要区域。

5.方法区

各个线程共享的内存区域,存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据,

运行时常量池是方法区的一部分,它是每一个类或接口的常量池的运行时表示形式,存放编译期间生成的各种字面量,符号引用,在类加载后进入方法区的运行时常量池储存。
运行时常量池相对于普通class文件的常量池的另一个特性是动态性,java并不要求常量只有编译期间产生,并非Class文件常量池中的常量才可以进入运行时常量池,运行期间也可将新的常量放入池中,例如String 类的intern()方法。

图待附

原文地址:https://www.cnblogs.com/wangxiaopei/p/8551254.html