JVM常量池

JVM中的常量池主要有以下几个类别,它们各自在JVM中的位置随着JDK版本的演进而有所变化:

  1. Class文件常量池

    • 位置 :存在于每个独立的.class文件中。这是编译期间生成的二进制文件的一部分,它包含了该类或接口的所有编译期常量,如字符串字面量、符号引用(类名、方法名、字段名)、整型和浮点数常量、类型描述符等。Class文件常量池是静态的,存在于磁盘上,不直接参与运行时内存管理。
  2. 运行时常量池

    • 位置 :在JVM启动后,当类被加载到内存时,JVM会为每个加载的类创建一个对应的运行时常量池。它是Class文件常量池在内存中的映射,也是方法区(Method Area)的一部分。运行时常量池存储的是在程序运行期间可能会动态生成的常量,如String.intern()方法提交的字符串,以及由符号引用解析得到的直接引用(如方法句柄、类句柄)等。对于JDK 6及更早版本 ,运行时常量池位于永久代(PermGen)中;从JDK 7开始,永久代被移除,取而代之的是元空间(Metaspace),此时运行时常量池也被转移到了元空间中。
  3. 字符串常量池

    • 位置 :字符串常量池是运行时常量池的一个重要组成部分,专门用来存储字符串字面量。在JDK 6及以前 ,字符串常量池位于永久代的方法区 内。从JDK 7开始 ,字符串常量池被移出方法区,**直接放入了堆(Heap)**中。这一变化主要是为了缓解方法区空间不足导致的性能问题,以及更容易进行垃圾回收。至今(包括JDK 8及之后版本),字符串常量池仍然保留在堆中。
  4. 基本类型包装类常量池(可能存在的概念)

    • 这个概念在一些资料中提及,但并未成为JVM规范的一部分。它通常指代JVM可能对Integer、Long等基本类型包装类的对象进行的一种内部缓存机制。例如,对于[-128, 127]范围内的Integer值,JVM可能会在某个固定区域(如堆中)维护一个缓存,重复使用相同的对象实例,以减少对象创建的数量。然而,这并非严格意义上的"常量池",因为其存放的是可变的、短暂存在的对象实例,而不是编译期或运行期确定不变的常量。

综上所述,不同类型的常量池在JVM中的位置如下:

  • Class文件常量池:存储在磁盘上的.class文件中。
  • 运行时常量池:JDK 6及以前位于永久代(PermGen),JDK 7及以后位于元空间(Metaspace)。
  • 字符串常量池:JDK 6及以前位于永久代的方法区,JDK 7及以后位于堆(Heap)。

请注意,上述信息基于已知的JDK版本发展情况,具体实现可能会因JVM的具体实现(如HotSpot、OpenJ9等)和版本细节有所不同。随着JVM技术的持续演进,未来可能存在进一步的变化。如果您在处理特定版本的JVM时,建议查阅对应版本的官方文档或最新研究资料以获取最准确的信息。

相关推荐
2303_821287381 小时前
c++ RAII机制详解 c++如何利用RAII管理资源
jvm·数据库·python
Sam_Deep_Thinking1 小时前
为什么选微服务而不是动态扩容单体
java·jvm·微服务
m0_624578592 小时前
C#怎么获取U盘的插拔事件_C#如何重写WndProc捕获消息【进阶】
jvm·数据库·python
2301_781571424 小时前
JavaScript中Object-getOwnPropertySymbols获取方法
jvm·数据库·python
苍煜5 小时前
生产环境 JVM 参数实战计算指南
jvm
敲敲千反田6 小时前
ThreadLocal和CompletableFuture
java·网络·jvm
Hammer_Hans7 小时前
DFT笔记45
java·jvm·笔记
过期动态7 小时前
【RabbitMQ基础篇】RabbitMQ从入门到实战
java·jvm·数据库·分布式·spring·rabbitmq·intellij-idea
阿维的博客日记9 小时前
Bean 会被 JVM 回收吗?
jvm·spring
liann11910 小时前
Agent 内存马禁止 Attach JVM
java·jvm·安全·网络安全·系统安全·网络攻击模型·信息与通信