「运行时数据区」——程序计数器、虚拟机栈( 五 )
基于栈式架构的虚拟机所使用的零地址指令更加紧凑 , 但完成一项操作的时候必然需要使用更多的入栈和出栈指令 , 这同时也就意味着将需要更多的指令分派(instruction dispatch)次数和内存读/写次数 。
由于操作数是存储在内存中的 , 因此频繁地执行内存读/写操作必然会影响执行速度 。 为了解决这个问题 , HotSpot JVM的设计者们提出了栈顶缓存(Tos , Top-of-Stack Cashing)技术 ,将栈顶元素全部缓存在物理CPU的寄存器中 , 以此降低对内存的读/写次数 , 提升执行引擎的执行效率。
3.5 动态链接每一个栈帧内部都包含一个指向 运行时常量池中该栈帧所属方法的引用。 包含这个引用的目的就是为了支持当前方法的代码能够实现 动态链接(Dynamic Linking)。 比如invokedynamic指令 。
在Java源文件被编译到字节码文件中时 , 所有的变量和方法引用都作为符号引用(Symbolic Reference)保存在class文件的常量池里 。 比如:描述一个方法调用了另外的其他方法时 , 就是通过常量池中指向方法的符号引用来表示的 , 那么 动态链接的作用就是为了将这些符号引用转换为调用方法的直接引用。文章插图
常量池的作用:就是为了提供一些符号和常量 , 便于指令的识别 。
3.6 方法返回地址当一个方法开始执行后 , 只有两种方式可以退出这个方法:
- 正常执行完成
- 出现未处理的异常
- 一个方法在正常调用完成之后 , 究竟需要使用哪一个返回指令 , 还需要根据方法返回值的实际数据类型而定 。
- 在字节码指令中 , 返回指令包含ireturn(当返回值是boolean , byte , char , short和int类型时使用) , lreturn(Long类型) , freturn(Float类型) , dreturn(Double类型) , areturn 。 另外还有一个return指令声明为void的方法 , 实例初始化方法 , 类和接口的初始化方法使用 。
无论通过哪种方式退出 , 在方法退出后都返回到该方法被调用的位置 。 方法正常退出时 ,调用者的PC寄存器的值作为返回地址 , 即调用该方法的指令的下一条指令的地址。 而通过异常退出的 , 返回地址是要通过异常表来确定 , 栈帧中一般不会保存这部分信息 。
本质上 , 方法的退出就是当前栈帧出栈的过程 。 此时 , 需要恢复上层方法的局部变量表、操作数栈、将返回值压入调用者栈帧的操作数栈、设置PC寄存器值等 , 让调用者方法继续执行下去 。
正常完成出口和异常完成出口的区别在于: 通过异常完成出口退出的不会给他的上层调用者产生任何的返回值。
3.7 附加信息《Java虚拟机规范》允许虚拟机实现增加一些规范里没有描述的信息到栈帧之中 , 例如与调试、性能收集相关的信息 , 这部分信息完全取决于具体的虚拟机实现 , 这里不再详述 。
参考深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)
运行时数据区Oracle官网介绍
原文地址:
【「运行时数据区」——程序计数器、虚拟机栈】原文作者:凯宝宝
- 彼尔姆|机器人公司想用 20 万美元「买断」你的脸,如果它足够友好
- 融资丨端到端通用AI智能制造平台提供商「依瞳科技」完成新一轮融资,卓源资本领投
- 新浪科技|蜂花、拉夏贝尔学会了「鸿星尔克式营销」,但结局却完全不同
- 原叶茶|联合利华「贱卖」立顿,袋泡茶的国产替代来了?丨氪金Lite
- 计费规则|关于「高德打车」用户体验的若干思考
- CPU|「小狮子诊所」内存时序到底有什么作用?
- 柳叶刀|融资丨「柳叶刀机器人」完成Pre-A+轮融资,聚焦骨科及口腔手术智能化
- 深至科技|融资丨「深至科技」完成近亿元C1轮融资,助AI医学影像真正走入基层医疗
- 退市|「PW热点」滴滴出行:即日起启动在纽交所退市的工作
- 西贝|蜂花、拉夏贝尔学会了「鸿星尔克式营销」,但结局却完全不同