JVM 中的 returnAddress过程详解

 更新时间:2022年04月29日 09:21:57   作者:m0_67402013  
JVM的毕竟是个虚拟机,是一种规范,虽说符合冯诺依曼的计算机设计理念,但是他并不是实体计算机,所以他的组成也不是什么存储器,控制器,运算 器,输入输出设备,本文给大家介绍JVM 中的 returnAddress,感兴趣的朋友一起看看吧

JVM是虚拟机,也是一种规范,他遵循着冯·诺依曼体系结构的设计原理。冯·诺依曼体系结构中,指出计算机处理的数据和指令都是二进制数,采用存储 程序方式不加区分的存储在同一个存储器里,并且顺序执行,指令由操作码和地址码组成,操作码决定了操作类型和所操作的数的数字类型,地址码则指出地址码和 操作数。从dos到window8,从unix到ubuntu和CentOS,还有MAC OS等等,不同的操作系统指令集以及数据结构都有着差异,而JVM通过在操作系统上建立虚拟机,自己定义出来的一套统一的数据结构和操作指令,把同一套语 言翻译给各大主流的操作系统,实现了跨平台运行,可以说JVM是java的核心,是java可以一次编译到处运行的本质所在。

参考文档:jvms12

数据类型

在 JVM 中,数据分为两大类:primitive types (原生类型)和 reference types(引用类型)。

引用类型,让 JVM 能更好的支持于面向对象语言的设计,引用类型的值用来指向内存中分配的类实例或者数组。JVM 规范中并没有详细规定引用类型的实现细节,比如引用应该通过何种方式去定位、访问堆中的对象,具体的对象访问方式取决于虚拟机的具体实现,比如 HotSpot 有其自己的实现方案。

目前主流的访问方式有使用句柄和直接指针两种:

其中使用直接指针访问的方式,类似于 C++ 中的虚表(虚表就是指向对象类型数据的指针)。这两种对象访问方式各有优劣,使用句柄访问的最大好处就是 reference 中存储的是稳定的句柄地址,在对象被移动(比如垃圾回收时,整理内存空间,会移动对象的存储位置)时只会改变句柄中示例数据的指针,而 reference 本身不需要修改。

使用直接指针访问的最大好处就是速度更快,节省了一次内存寻址的时间开销。

原生数据类型包括:numeric types, boolean type, returnAddress type。其中 returnAddress 数据只存在于字节码层面,与编程语言无关,也就是说,我们在 Java 语言中是不会直接与 returnAddress 类型的数据打交道的。

returnAddress 类型的值是指向字节码的指针,不管是物理机还是虚拟机,运行时内存中的数据总归可分为两类:代码,数据。对于冯诺依曼结构的计算机,指令数据和数值数据都存储在内存中,而哈弗结构的计算机,将程序指令与数据分开存储。

对于 JVM 来说,程序就是存储在方法区的字节码指令,而 returnAddress 类型的值就是指向特定指令内存地址的指针。

JVM支持多线程,每个线程有自己的程序计数器(pc register),而 pc 中的值就是当前指令所在的内存地址,即 returnAddress 类型的数据,当线程执行 native 方法时,pc 中的值为 undefined。

栈帧

栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构,栈帧中存储了方法的局部变量表,操作数栈,动态连接,和方法返回地址等信息。在程序编译时,栈帧中需要多大的局部变量表,多深的操作数栈都已经完全确定了,并且写在方法表的 Code 属性中。

当一个方法开始执行后,只有两种方式可以退出,第一种方式是执行引擎遇到任意一个方法返回的字节码指令,这种方式称为正常完成出口;另外一种退出方式是,在方法执行过程中遇到异常,且该异常没有被被捕获,称为异常完成出口。

无论是哪种退出方式,在方法退出后,都需要返回到该方法被调用的位置(地址),让程序继续执行。一般来说,方法执行前,会保存调用者当前的 PC 计数器中的值,当方法正常退出时,将该 PC 计数器的值会作为返回地址,返回给调用者。在方法异常退出时,返回地址是通过异常处理器表来确定的。

方法退出的过程实际上就等于把当前栈帧出栈,一般过程为:

  • 恢复上层方法的局部变量表和操作数栈
  • 把返回值压入调用者栈帧的操作数栈中
  • 调整 PC 计数器的值,以指向方法调用指令后面的一条指令

到此这篇关于JVM 中的 returnAddress的文章就介绍到这了,更多相关JVM returnAddress内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅谈Spring的两种事务定义方式

    浅谈Spring的两种事务定义方式

    下面小编就为大家带来一篇浅谈Spring的两种事务定义方式。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • java jvm两种存储区的类型知识点讲解

    java jvm两种存储区的类型知识点讲解

    在本篇文章里小编给大家整理的是一篇关于java jvm两种存储区的类型知识点讲解内容,有兴趣的朋友们可以学习下。
    2021-03-03
  • java的arrays数组排序示例分享

    java的arrays数组排序示例分享

    排序算法,基本的高级语言都有一些提供。C语言有qsort()函数,C++有sort()函数,java语言有Arrays类(不是Array)。用这些排序时,都可以写自己的排序规则
    2014-02-02
  • java设计模式之装饰模式详细介绍

    java设计模式之装饰模式详细介绍

    这篇文章主要介绍了java设计模式之装饰模式,有需要的朋友可以参考一下
    2013-12-12
  • Java 并发编程之ThreadLocal详解及实例

    Java 并发编程之ThreadLocal详解及实例

    这篇文章主要介绍了Java 并发编程之ThreadLocal详解及实例的相关资料,需要的朋友可以参考下
    2017-02-02
  • JAVA基础快速从入门到精通

    JAVA基础快速从入门到精通

    Java是一门面向对象的编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征
    2022-03-03
  • Springboot @Import 详解

    Springboot @Import 详解

    这篇文章主要介绍了Springboot @Import 详解,仔细看了下Springboot关于@Import的处理过程,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • Java IO流之原理分类与节点流文件操作详解

    Java IO流之原理分类与节点流文件操作详解

    流(Stream)是指一连串的数据(字符或字节),是以先进先出的方式发送信息的通道,数据源发送的数据经过这个通道到达目的地,按流向区分为输入流和输出流
    2021-10-10
  • java基于C/S结构实现多线程聊天室

    java基于C/S结构实现多线程聊天室

    这篇文章主要为大家详细介绍了java基于C/S结构实现多线程聊天室,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • Spring Boot的listener(监听器)简单使用实例详解

    Spring Boot的listener(监听器)简单使用实例详解

    监听器(Listener)的注册方法和 Servlet 一样,有两种方式:代码注册或者注解注册。接下来通过本文给大家介绍Spring Boot的listener(监听器)简单使用,需要的朋友可以参考下
    2017-04-04

最新评论