当前位置: 首页 > news >正文

JVM方法区的运行时常量区到底存储哪些数据?

 JDK8以后,运行时常量池逻辑上属于方法区;但:

  • 其中的字符串常量池实际位置移至到了java堆;
  • 其中一些符号引用也存储到了元空间;
  • 字符串常量池,元空间,运行时常量区的具体关系请看这篇博客:
    JDK8+后,运行时常量池、字符串常量池和元空间的关-CSDN博客

        JVM 方法区(Method Area) 中的 运行时常量池(Runtime Constant Pool) 存储的数据来源于 类文件常量池(Class File Constant Pool),并在运行时进行动态解析和扩展。具体存储的内容可以分为以下几类:


1. 类文件常量池的原始数据(编译期生成)

.class 文件中,常量池(Constant Pool)存储了各种符号信息,JVM 在加载类时会将其解析到运行时常量池。主要包括:

(1) 字面量(Literals)

  • 字符串常量String):如 "Hello"(最终可能被放入字符串池 String Table)。

  • 数值常量

    • 整型(int, long, short, byte, char):如 123, 0x1F

    • 浮点型(float, double):如 3.14, 2.71828

  • final 常量(无论是否 static):

    • static final int MAX = 100;(静态常量)

    • final String NAME = "Java";(实例常量)

(2) 符号引用(Symbolic References)

  • 类和接口的全限定名(Fully Qualified Name):如 java/lang/String

  • 字段的名称和描述符(Field Name & Descriptor):

    • Ljava/lang/String;(字段类型描述符)。

  • 方法的名称和描述符(Method Name & Descriptor):

    • main([Ljava/lang/String;)Vmain 方法的描述符)。

  • 方法句柄(MethodHandle)和动态调用点(InvokeDynamic)信息(Java 7+)。


2. 运行时动态解析的数据

在类加载、链接(验证、准备、解析)阶段,JVM 会将符号引用转换为直接引用:

  • 类/接口的解析:将 java/lang/Object 转换为实际类对象的引用。

  • 字段解析:将字段符号引用转换为内存偏移量或 Field 对象。

  • 方法解析:将方法符号引用转换为方法入口地址(Method 对象或 JNI 指针)。

  • 动态计算的常量(Java 8+):

    • CONSTANT_Dynamicinvokedynamic 指令使用的动态常量)。


3. 动态生成的常量

  • String.intern() 的字符串

    • 调用 "abc".intern() 后,字符串会被放入字符串池(String Table),逻辑上属于运行时常量池的一部分(但 HotSpot 的字符串池在堆中)。

  • 动态代理类、Lambda 表达式生成的类信息(可能涉及新的常量池条目)。

  • Class 对象引用:如 String.class 的运行时表示。


4. 其他 JVM 内部使用的数据

  • 基本类型的包装类缓存

    Integer.valueOf(1) 会缓存 -128~127,这些值可能被复用。
  • 特殊常量

    null 的表示,以及某些 JVM 内部使用的标记常量(如异常类名)。

总结:运行时常量池存储哪些数据?

数据类型示例是否动态解析
字符串常量"Hello"可能 intern()
数值常量123, 3.14
final 常量static final int X=1可能内联优化
类和接口全限定名java/lang/String解析为 Class
字段/方法符号引用Ljava/lang/String;解析为直接引用
动态计算的常量CONSTANT_Dynamic(Java 8+)运行时计算
String.intern()"abc".intern()动态添加

关键点

  1. 运行时常量池不仅存储静态常量,还包括所有类文件的常量池信息 + 运行时解析的数据。

  2. 符号引用会在类加载时解析,变成直接引用(如内存地址、方法指针等)。

  3. 字符串常量可能被 intern() 并放入字符串池(HotSpot 中字符串池在堆,但逻辑属于运行时常量池)。

  4. 动态语言支持(如 invokedynamic 会新增动态计算的常量。

如果你对某部分内容(如字符串池、符号引用解析)想深入了解,可以进一步讨论!


 常见误区澄清

  • 误区:“运行时常量池只存静态常量”。 事实:它存储所有类文件常量池的内容,包括动态解析的引用和字面量。

  • 字符串池的特殊性: 在HotSpot JVM中,字符串池(String Table)实际位于堆内存,而非方法区,但逻辑上属于运行时常量池的一部分。


静态 vs. 非静态常量

  • 静态常量(static final: 例如 public static final int MAX = 100;,这类常量会被存入运行时常量池,但它们的可能进一步被内联到使用它们的代码中(编译期优化)。

  • 非静态常量(实例级final常量): 例如 private final String name = "Hello";,虽然字面量 "Hello" 会存储在运行时常量池中,但该常量值是与对象实例绑定的,需要通过实例访问。

http://www.dtcms.com/a/274808.html

相关文章:

  • 【南金研CAN数采仪助力福田祥菱 QEV车型售后问题处理
  • 制作 ext4 文件系统
  • java 导入利用布隆BloomFilter
  • SSE事件流简单示例
  • Paimon 写入磁盘文件名字生成机制
  • 2025年NSSCTF-青海民族大学 2025 新生赛WP
  • 学习C++、QT---20(C++的常用的4种信号与槽、自定义信号与槽的讲解)
  • 动力系统模拟与推导-AI云计算数值分析和代码验证
  • BLE低功耗设计:从广播模式到连接参数优化的全链路分析与真题解析
  • Django母婴商城项目实践(一)
  • 【JMeter】接口加密
  • 蜗轮丝杆升降机拆装图
  • 在多个DHCP服务器的网络环境中选择指定的DHCP服务
  • Windows GNU Radio避坑
  • 深入探究编程拷贝
  • mysql的性能优化:组提交、数据页复用、全表扫描优化、刷脏页
  • Vue 表单开发避坑指南:从响应式数据到动态规则的实践总结
  • Go 编译报错排查:vendor/golang.org/x/crypto/cryptobyte/asn1 no Go source files
  • Java外包怎么选?这几点不注意,项目可能血亏!
  • day21——特殊文件:XML、Properties、以及日志框架
  • Linux中geoserver中文乱码
  • 离线环境二进制安装docker
  • uniapp获取状态栏高度,胶囊按钮的高度,底部安全区域的高度,自定义导航栏
  • [实战]调频三角波和锯齿波信号生成(完整C代码)
  • hbuilderx打包的应用上传苹果应用商店最简方法
  • 字节豆包又一个新功能,超级实用,4 种玩法,你肯定用得上!(建议收藏)
  • Uniapp视频聊天软件内容监控插件开发指南
  • OA系统中的搜索功能方案:简单搜索vs高级搜索
  • 2-Git提交本地项目到远程仓库
  • 问有几条病狗?