JVM学习笔记(二)——虚拟机运行数据区域探索
栈帧的结构:
每一个被线程执行的方法,为该栈中的栈帧,即每个方法对应一个栈帧。
那么栈帧里面包含了什么呢?
请往下看,有如下几种东西:
局部变量表(Local Variables):
这里存放着方法中定义的局部变量以及方法的参数,但是局部变量表中的变量并不是直接使用的,使用时必须通过相关指令将其加载至操作数栈中作为操作数使用。
操作数栈(Operand Stack)):
存储操作数的地方,这里的操作也是出栈和压栈
动态链接(Dynamic Linking):
栈帧里包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接,这句话用点难理解,具体意思如下:
Class文件的常量池中存有大量的符号引用,字节码中的方法调用指令就以常量池中指向方法的符号引用为参数。这些符号引用一部分会在类加载阶段或第一次使用的时候转化为直接引用,这种转化称为静态解析。另外一部分将在每一次的运行期期间转化为直接引用,这部分称为动态连接。
方法返回地址(Return Address):
当一个方法开始执行后,只有两种方式可以退出,一种是遇到方法返回的字节码指令;一种是遇见异常,并且 这个异常没有在方法体内得到处理。
不管是哪一种方法的退出,都要回到方法被调用的位置,程序才能继续执行。所以栈帧里面需要保存方法返回地址,以便程序恢复方法的执行状态。
附加信息:
虚拟机规范允许具体的虚拟机实现增加一些规范里没有描述的信息到栈帧中,但是一般会把动态连接,方法返回地址与其它附加信息全部归为一类,称为栈帧信息。
数据区域之间的指向:
既然栈帧中存在局部变量,那么当这个变量是引用类型,如String,那么这时候就是栈中元素指向堆,堆中存着对象,栈中的元素就存着对象的引用地址。
堆的数据区域划分:
Eden区:
Survivor区:
同一时间内,From(S0)和To(S1)只能一个空间存在数据,另外一个空间为空。
Old区
Old区都是年龄比较大的对象,或者相对超过了某个阈值的对象。 Old区也会有GC的操作,叫做Major GC。
对象的故事:
我是一只对象,出生在Eden区,Eden区有很多和我是同一个物种的小伙伴,玩的很开心。但是慢慢的,Eden区的小伙伴越来越多,特别的挤,去哪都是人挤人。
Eden区长下了死命令,抽取部分人到 Survivor的From区去,这里很不稳定,老是在From和To之间来回徘徊。又过了好一段时间,Survivor的区长也来赶人了,要把
像我这种大龄骚年赶走,好吧,又要背井离乡了。走着走着,我来到了Old区,在这里都是大龄的伙伴啊,最后就在这里安享晚年了。