我们都知道,JVM的垃圾收集机制能够帮开发者自动管理内存,了解JVM运行时的内存结构是理解垃圾收集机制的前提。本文主要简单介绍JVM运行时的内存结构。
【JVM运行时内存中不同的数据区域】
一、PC寄存器
做过嵌入式开发或者底层编程的朋友应该都知道PC寄存器的作用,它就相当于在程序流中的游标,指示线程当前的运行位置。但是要注意,如果虚拟机执行的是本地native方法,则PC寄存器为undefined状态。
一个线程持有一个独立的PC寄存器。
二、java栈
每一个JVM线程都会拥有一个java栈,java栈伴随着线程的创建而创建。java栈中存放着多个java帧,至于什么是java帧会在文章后面介绍。
三、java堆
JVM所有线程之间共享,存放类实例和数组对象。
四、方法区
JVM所有线程之间共享,存放编译代码。
五、运行时常量池
JVM所有线程之间共享,存放在方法区中,对应于class文件中每一个类或者接口的常量池表。
六、本地方方法栈
一个线程拥有一个,在native方法执行时使用。
【栈帧介绍】
线程中的每个方法被调用的时候JVM都会生成一个栈帧,栈帧存放在线程的java栈中。栈帧主要保存一下几种内存类型。
一、局部变量表
一个变量列表。变量的类型是原生类型或者引用类型。这里面存放都是局部变量,比如说方法的参数和方法内部定义的变量。一个java程序在编译成class文件的时候局部变量表的最大容量就已经被确定了。
二、操作数栈
存放操作数,如相加指令中的两个加数和结果。
三、动态链接
要理解动态了解首先要了解JVM对方法的调用过程。JVM的运行时常量池保存了大量的符号引用,有些符号引用可以看成是方法的间接引用。JVM在需要调用某个方法时需要将符号引用(也就是方法的间接引用)转变成方法在内存中的直接引用。如果JVM是在类加载或者引用符号第一次使用的时候将引用符号转变成方法的直接引用,这种转换叫静态链接;如果JVM是在运行期间将引用符转变成方法的直接引用,则这种转变叫做动态链接。
简单来说,栈帧中的动态链接就是帮助JVM在执行某个方法是调用其他方法。
四、方法的返回
JVM的方法返回分为两种情况,一种是正常结束返回,另外一种是异常结束返回。正常结束返回时,方法会把返回值交给方法的调用者;异常结束时,方法不会有返回值,而是让调用者处理异常。