JVM之符号引用和直接引用

简介: 本文介绍了Java中直接引用和符号引用的概念及其区别。直接引用与虚拟机布局相关,包括指向目标的指针、相对偏移量或间接句柄,通常在目标已被加载到内存时使用。符号引用则涉及编译原理,包含类/接口全限定名、字段及方法的名称和描述符,在Class文件中保存,需在运行时解析为具体内存地址。文中还详细说明了描述符规则以及数组类型的表示方式,帮助理解Java虚拟机的动态链接过程。

直接引用

直接引用和虚拟机的布局是相关的,不同的虚拟机对于相同的符号引用所翻译出来的直接引用一般是不同的。如果有了直接引用,那么直接引用的目标一定被加载到了内存中。 直接引用可以是:

  1. 直接指向目标的指针。(个人理解为:指向对象,类变量和类方法的指针)
  2. 相对偏移量。(指向实例的变量,方法的指针)
  3. 一个间接定位到对象的句柄。

符号引用

符号引用则属于编译原理方面的概念,包括了下面三类常量:

  1. 类和接口的全限定名(Fully Qualified Name)
  2. 字段的名称和描述符(Descriptor)
  3. 方法的名称和描述符
符号引用存在原因:

Java代码在进行Javac编译的时候,并不像C和C++那样有“连接”这一步骤,而是在虚拟机加载Class文件的时候进行动态连接。也就是说,在Class文件中不会保存各个方法、字段的最终内存布局信息,因此这些字段、方法的符号引用不经过运行期转换的话无法得到真正的内存入口地址,也就无法直接被虚拟机使用。当虚拟机运行时,需要从常量池获得对应的符号引用,再在类创建时或运行时解析、翻译到具体的内存地址之中。

类的全限定名

类的全限定名称很好理解,比如Object类他的包名为java.lang,所以他的全限定名就是java/lang/Object,他仅仅是把类中的“.”替换为“/”而已,为了让多个全限定名不会混乱,一般会在结尾添加";"表示结束。

简单名称

简单名称就是指没有参数修饰和类型的方法或者字段名,比如clone()方法的简单名称就是clone,字段a的简单名称就是m;

描述符

相对于全限定名和简单名称来说,方法和字段的描述符就要复杂一些。描述符的作用是 用来描述字段的数据类型、方法的参数列表(包括数量、类型以及顺序)和返回值。根据描述符规则,基本数据类型(byte、char、double、float、int、long、short、boolean)以及代表 无返回值的void类型都用一个大写字符来表示,而对象类型则用字符L加对象的全限定名来表示。

对于数组类型,每一个维度将使用一个前置的“[”,二维数组则使用两个“[, 如一个定义为 ”java.lang.String[][]“的二维类型的数组,将被记录为:“[[Ljava/lang/String;”,一个整型数 组“int[]”将被记录为“[I”。

描述符描述方法的时候,按照先参数列表,后返回值的顺序描述,参数列表按照参数的严格顺序放在一组小括号“()”之内。如方法void inc()的描述符为“()V”,方法 java.lang.String toString()的描述符为“()Ljava/lang/String;”,方法int indexOf(char[]source,int sourceOffset,int sourceCount,char[]target,int targetOffset,int targetCount,int fromIndex)的描述符为“([CII[CIII)I”。


转载来源:https://juejin.cn/post/6844904024773230606

相关文章
|
Java 开发者 微服务
SpringBoot启动流程大揭秘
通俗易懂读源码--SpringBoot启动流程详解
SpringBoot启动流程大揭秘
|
5月前
|
监控 负载均衡 关系型数据库
读写分离实战:提升MySQL并发处理能力
本文深入解析了MySQL读写分离的核心策略,涵盖架构设计、应用层及中间件实现、负载均衡、数据一致性保障、故障处理、性能监控与实战部署方案,助你构建高性能数据库架构,提升系统吞吐量与可用性。
|
消息中间件 存储 安全
如何理解符号引用和直接引用?
如何理解符号引用和直接引用?
251 11
如何理解符号引用和直接引用?
|
6月前
|
Java 关系型数据库 数据库
深度剖析【Spring】事务:万字详解,彻底掌握传播机制与事务原理
在Java开发中,Spring框架通过事务管理机制,帮我们轻松实现了这种“承诺”。它不仅封装了底层复杂的事务控制逻辑(比如手动开启、提交、回滚事务),还提供了灵活的配置方式,让开发者能专注于业务逻辑,而不用纠结于事务细节。
|
11月前
|
缓存 Java 数据库连接
Mybatis一级缓存、二级缓存详讲
本文介绍了MyBatis中的查询缓存机制,包括一级缓存和二级缓存。一级缓存基于同一个SqlSession对象,重复查询相同数据时可直接从缓存中获取,减少数据库访问。执行`commit`操作会清空SqlSession缓存。二级缓存作用于同一namespace下的Mapper对象,支持数据共享,需手动开启并实现序列化接口。二级缓存通过将数据存储到硬盘文件中实现持久化,为优化性能,通常在关闭Session时批量写入缓存。文章还说明了缓存的使用场景及注意事项。
407 7
Mybatis一级缓存、二级缓存详讲
|
11月前
|
存储 Java 编译器
Java泛型类型擦除以及类型擦除带来的问题
本文主要讲解Java中的泛型擦除机制及其引发的问题与解决方法。泛型擦除是指编译期间,Java会将所有泛型信息替换为原始类型,并用限定类型替代类型变量。通过代码示例展示了泛型擦除后原始类型的保留、反射对泛型的破坏以及多态冲突等问题。同时分析了泛型类型不能是基本数据类型、静态方法中无法使用泛型参数等限制,并探讨了解决方案。这些内容对于理解Java泛型的工作原理和避免相关问题具有重要意义。
603 0
|
11月前
|
存储 人工智能 数据可视化
ModelScope魔搭25年3月发布月报
在这个春天里,小鲸鱼的DeepSeek-R1系列在模型社区掀起的巨大浪潮尚未平息,我们又迎来了千问的QwQ-32B正式版本,社区在Reasoning模型上的热情还在升温。除此之外,业界其他模型在过去一
297 1
|
消息中间件 中间件 Kafka
分布式事务最全详解 ,看这篇就够了!
本文详解分布式事务的一致性及实战解决方案,包括CAP理论、BASE理论及2PC、TCC、消息队列等常见方案,助你深入理解分布式系统的核心技术。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
分布式事务最全详解 ,看这篇就够了!
|
存储 缓存 Java
大厂面试高频:Volatile 的实现原理 ( 图文详解 )
本文详解Volatile的实现原理(大厂面试高频,建议收藏),涵盖Java内存模型、可见性和有序性,以及Volatile的工作机制和源码案例。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:Volatile 的实现原理 ( 图文详解 )
|
easyexcel Java UED
SpringBoot中大量数据导出方案:使用EasyExcel并行导出多个excel文件并压缩zip后下载
在SpringBoot环境中,为了优化大量数据的Excel导出体验,可采用异步方式处理。具体做法是将数据拆分后利用`CompletableFuture`与`ThreadPoolTaskExecutor`并行导出,并使用EasyExcel生成多个Excel文件,最终将其压缩成ZIP文件供下载。此方案提升了导出效率,改善了用户体验。代码示例展示了如何实现这一过程,包括多线程处理、模板导出及资源清理等关键步骤。