Java虚拟机(JVM)中符号引用(symbolic reference)和直接引用以及转化过程

在Java虚拟机(JVM)中,符号引用(symbolic reference)和直接引用(direct reference)是两种不同的引用方式。了解这两种引用方式有助于更深入地理解Java的运行时机制,特别是类加载和方法调用的过程。

1. 符号引用 (Symbolic Reference)

符号引用是一种通过名称来引用目标的方式。符号引用在编译时生成,并存储在类文件的常量池中。常量池中的符号引用可以是以下几种:

  • 类或接口的全限定名(如:java/lang/String)。
  • 字段的名称和描述符(如:value:[C)。
  • 方法的名称和描述符(如:length:()I)。

2. 直接引用 (Direct Reference)

直接引用是指实际指向目标的内存地址或偏移量。这种引用方式在运行时由JVM解析符号引用后生成,指向具体的内存位置,便于快速访问。

3. 符号引用转化为直接引用的过程

在Java程序运行时,符号引用需要被解析成直接引用,这个过程称为解析(Resolution)。这个过程通常发生在类加载的链接阶段的解析步骤,或者在首次使用符号引用时(如首次访问某个字段或调用某个方法)。

具体步骤如下:

  1. 类加载阶段

    • 类加载器读取类文件并创建对应的类对象。
    • JVM在链接阶段处理类的常量池中的符号引用,将其解析为直接引用。
  2. 首次使用符号引用

    • 当程序首次访问某个字段、方法或类时,JVM会查找并验证该符号引用是否存在。
    • 一旦找到目标,JVM将符号引用转换为直接引用,并将其存储在常量池中,以便后续快速访问。

示例

假设有以下Java代码:

String str = "Hello, World!";
int length = str.length();

在上述过程中,str 是一个变量引用,它指向一个 String 对象。在Java中,变量引用可以理解为以下两种情况之一:

  1. 符号引用(Symbolic Reference):在编译时,str 变量是通过符号引用来表示的。它被存储在类文件的常量池中,作为符号引用的一部分。这种引用形式仅在编译时存在,用于标识变量的名称和类型。

  2. 直接引用(Direct Reference):在运行时,str 变量会变成一个实际的内存地址,指向堆内存中的 String 对象。这种引用形式在程序运行时存在,用于直接访问对象的实际内存位置。

3.1 编译阶段(符号引用)

在编译阶段,代码中的变量 str 是一个符号引用。编译器将 str 变量的名称和类型信息存储在类文件的常量池中。例如,常量池中会有类似这样的符号引用:

  • #1 = Fieldref #2.#3 // String str
  • #2 = Class #4 // CurrentClass
  • #3 = NameAndType #5:#6 // str:Ljava/lang/String;
  • #4 = Utf8 "CurrentClass"
  • #5 = Utf8 "str"
  • #6 = Utf8 "Ljava/lang/String;"
3.2运行时(直接引用)

在运行时,JVM加载类文件并分配内存,变量 str 将被初始化为指向实际的 String 对象。假设代码如下:

String str = "Hello, World!";

在运行时,str 变量会成为一个直接引用,指向堆内存中存储的 "Hello, World!" 字符串对象。

3.4 具体过程
  1. 类加载和初始化:当类加载器加载包含 str 变量的类时,JVM会根据类文件中的常量池信息创建类对象,并在类加载时分配静态变量和实例变量的内存。
  2. 对象创建:在执行 String str = "Hello, World!"; 时,JVM会在堆内存中分配一个 String 对象,并初始化为 "Hello, World!"
  3. 变量引用str 变量会被赋值为指向这个 String 对象的内存地址。此时,str 是一个直接引用,指向堆内存中的字符串对象。

在Java中,变量 str 在编译时是符号引用,用于标识变量名称和类型。在运行时,str 变成一个直接引用,指向堆内存中的实际对象。通过这种方式,JVM能够高效地管理内存和访问对象。

同时在编译时,编译器会将对str.length()的调用记录为符号引用,存储在常量池中。在运行时,当JVM第一次解析str.length()时:
JVM会查找String类的length方法。
确认length方法的存在并加载对应的类。
将符号引用str.length()解析为直接引用,指向实际的length方法实现的内存地址。
后续对str.length()的调用将直接使用这个直接引用,避免再次解析符号引用。

4. 总结

符号引用转化为直接引用是Java虚拟机在运行时对程序代码进行优化的关键步骤。通过这种转换,JVM可以提高方法调用和字段访问的效率,从而提升Java程序的整体性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/36701.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jps命令解释以及用法

JPS命令是Linux系统中的一个常用命令,用于显示Java进程的相关信息。下面是JPS命令的详解: JPS命令是Java Development Kit(JDK)提供的一个工具,用于列出JVM进程(Java虚拟机进程)的信息。它通常…

39 - 安全技术与防火墙

39、安全技术和防火墙 一、安全技术 入侵检测系统:特点是不阻断网络访问,主要是提供报警和事后监督。不主动介入,默默看着你(监控)。 入侵防御系统:透明模式工作,数据包,网络监控…

TextArea是一个用于显示和编辑多行可滚动文本的控件,通常用于需要用户输入或展示大量文本的应用中

TextArea 是一个用于显示和编辑多行可滚动文本的控件,通常用于需要用户输入或展示大量文本的应用中。以下是 TextArea 中常用的属性、信号和方法的详解: 常用属性 text: 描述:用于设置或获取显示的文本内容。类型:string示例&…

python-(opencv)视频转glf

文章目录 前言python-(opencv)视频转glf1. 下载 opencv-python2. cv2(OpenCV)和imageio的区别3. demo源码 前言 如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。   而且听说…

youlai-boot项目的学习(4) 前后端本地部署

环境 1、macOS, brew, IntelliJ IDEA, WebStrom 2、后端:https://gitee.com/youlaiorg/youlai-boot.git , master, 9a753a2e94985ed4cbbf214156ca035082e02723 3、前端:https://gitee.com/youlaiorg/vue3-element-admin.git, master, 66b913ef01dc880ad…

mobaxterm x11 转发Ubuntu mac

目录 royal tsx —— 一款Mac平台MobaXterm平替工具 mobaxterm x11 转发Ubuntu 软件 royal tsx —— 一款Mac平台MobaXterm平替工具 Royal Apps Termius Mac mobaxterm x11 转发Ubuntu 软件 所以直接在 ssh 的时候加上 - X 就可以了 ssh -X -p xxx usernameIP 运行 xclock …

递归函数设计技巧

如何设计递归函数 要学会如何设计递归函数,首先要识别什么样的问题才适合递归函数求解,那么我们可以通过数学归纳法,分析问题,观察问题是否符合相关性质。 数学归纳法 数学归纳法,是一种基本的数学证明方法&#xff0c…

深度解析RocketMq源码-IndexFile

1.绪论 在工作中,我们经常需要根据msgKey查询到某条日志。但是,通过前面对commitLog分析,producer将消息推送到broker过后,其实broker是直接消息到达broker的先后顺序写入到commitLog中的。我们如果想根据msgKey检索一条消息无疑…

Zookeeper:基于Zookeeper的分布式锁

一、Zookeeper分布式锁原理 二、Zookeeper JavaAPI操作 1、Curator介绍 Curator是Apache Zookeeper的Java客户端。常见的Zookeeper Java API: 原生Java API。ZkClient。Curator。 Curator项目目标是简化Zookeeper客户端的使用。Curator最初是Netfix研发的&#xf…

LIMS系统选型时应该避免哪些误区呢

LIMS实验室管理系统在选型、实施及使用过程中,确实存在一些常见的误区。以下是对这些误区的详细解析和归纳: 一、误区 1、只关注功能而忽视用户需求 在LIMS系统的选型过程中,实验室可能过于关注系统的功能和技术特性,而忽视了实…

42.option方法给服务端和客户端配置参数

客户端是Bootstrap.option方法配置参数。 服务端有两个: 1.ServerBootstrap.option方法,给ServerSocketChannel配置参数的。 2.ServerBootstrap.childOption方法,给SocketChannel配置参数的。 package com.xkj.client;import com.xkj.message.*; import com.xkj.protoco…

K近邻回归原理详解及Python代码示例

K近邻回归原理详解 K近邻回归(K-Nearest Neighbors Regression, KNN)是一种基于实例的学习算法,用于解决回归问题。它通过找到输入数据点在特征空间中最相似的K个邻居(即最近的K个数据点),并使用这些邻居的…

C++11的可变参数模板

可变参数模板 什么是可变参数模板的可变参数展开参数包emplace系列函数引例emplace系列函数 什么是可变参数 printf和scanf中就涉及可变参数 这里三个点就代表可变参数,意思就是不管你传多少个参数,都可以接收 printf("%d",x); printf("…

狼牙山短视频:成都柏煜文化传媒有限公司

狼牙山短视频:记录自然与历史的交融 随着短视频的兴起,我们得以在短短几分钟内,跨越千山万水,领略世界各地的风情。成都柏煜文化传媒有限公司 而今天,我想带大家走进一个独特的地方——狼牙山,通过一系列短…

centos挂载新的磁盘

如果是vmware的话,在管理界面,为虚拟机创建一个新的磁盘,然后需要给这个磁盘分区 https://juejin.cn/post/6987200157733371935 1、执行如下命令,查询磁盘分区的UUID。 blkid 磁盘分区 以查询磁盘分区“/dev/vdb1”的UUID为例&am…

Spring Boot中的异常处理策略

Spring Boot中的异常处理策略 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将探讨在Spring Boot应用程序中如何有效地处理异常,保证系统的…

Transformer教程之Transformer的历史背景

在现代人工智能领域,Transformer模型已经成为一种不可或缺的技术,它在自然语言处理(NLP)和计算机视觉等多个领域取得了巨大的成功。本文将带你回顾Transformer的历史背景,了解它是如何从最初的构想到今天的广泛应用的。…

英国Essay写作攻略怎么才算详细?

写Essay是所有英国留学生都要面对的,很多刚到英国的留学生为了拿到一个完美的成绩单,都会选择找人Essay写作,从而拿到高分。可是你有没有想过,为什么Essay写作能拿高分,而自己写的Essay一直在及格线边上徘徊&#xff0…

Element-UI表单验证 二选一、三选一、多选一验证

Element-UI表单验证二选一验证 在表单提交过程中很多时候要用到几个表单项二选一验证或多选一验证,比如联系方式中的手机号和固定电话只需要填写一项就可通过验证,针对这样情况可以使用Element-UI的自定义验证实现,具体实现方法如下。 HTML…