1
xuanbg 2022-04-27 08:47:09 +08:00
当一个类被加载并且它在 JVM 中的运行时表示正在准备时,它的类加载器会分配元空间来存储类的元数据。所以很明显就是每个类一个元空间。
|
2
Sunhcer OP @xuanbg 我可以参考什么文献来证实这种说法吗?其实对于运行时常量池在堆区还是元空间也比较迷惑
|
3
xuanbg 2022-04-27 09:12:10 +08:00
常量池在元空间。因为常量和对象无关,所以 JVM 的设计就是把常量放元空间以节省内存。
|
4
xuanbg 2022-04-27 09:27:05 +08:00
|
5
JasonLaw 2022-04-27 10:36:53 +08:00 via iPhone
|
6
A1exlee 2022-04-27 11:14:50 +08:00
放在堆里的应该说的是字符串池,字符串池从 1.7 开始就从方法区移到堆里了。运行时常量池还是在元空间里
|
7
Sunhcer OP |
8
JasonLaw 2022-04-27 13:31:07 +08:00 via iPhone
@Sunhcer #7 具体的 JVM 实现要看文档,这本书更多的是在讲 JVM specification 。我也没怎么研究具体的 JVM 实现,sorry ,解答不了你的疑问。
|
9
weivi 2022-04-27 15:25:22 +08:00
可以去了解一下字节码文件的结构,其中就包括运行时常量池,可以在一定程度上解决你的疑问
|
11
weivi 2022-04-27 16:21:24 +08:00
@Sunhcer 是同一个东西 ,下面的内容摘自周志明的《深入理解 java 虚拟机》第三版
---------------------------------------------------------------------------------------------------------- 常量池中主要存放两大类常量:字面量( Literal )和符号引用( Symbolic References )。字面量比 较接近于 Java 语言层面的常量概念,如文本字符串、被声明为 final 的常量值等。而符号引用则属于编译 原理方面的概念,主要包括下面几类常量: ·被模块导出或者开放的包( Package ) ·类和接口的全限定名( Fully Qualified Name ) ·字段的名称和描述符( Descriptor ) ·方法的名称和描述符 ·方法句柄和方法类型( Method Handle 、Method Type 、Invoke Dynamic ) ·动态调用点和动态常量( Dynamically-Computed Call Site 、Dynamically-Computed Constant ) |
12
ikas 2022-04-27 16:23:04 +08:00 1
首先你先要分清楚 jvm 规范,与 jvm 的具体实现
jvm 规范中: 1.方法区域在逻辑上是堆的一部分,但是并不要求方法区域的位置 2.运行时常量池都是从 Java 虚拟机的方法区域分配的 具体的 jvm 实现,比如 openjdk8+: 永久生成的部分内容移动到 Java 堆,其余内容移动到本机内存 参考 https://docs.oracle.com/javase/specs/jvms/se18/html/jvms-2.html#jvms-2.5.4 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.4 http://openjdk.java.net/jeps/122 |
13
Sunhcer OP @weivi 是不同的,我跟倾向于这种说法:
class 文件常量池存储的是当 class 文件被 java 虚拟机加载进来后存放在方法区的一些字面量和符号引用,字面量包括字符串,基本类型的常量。 运行时常量池是当 class 文件被加载完成后,java 虚拟机会将 class 文件常量池里的内容转移到运行时常量池里,在 class 文件常量池的符号引用有一部分是会被转变为直接引用的。 |
14
Sunhcer OP @ikas 厉害了,我在这里找到一句话似乎可以终结疑问;
https://docs.oracle.com/javase/specs/jvms/se18/html/jvms-5.html The Java Virtual Machine maintains a run-time constant pool for each class and interface (§2.5.5). Java 虚拟机为每个类和接口维护一个运行时常量池; 那就是独立的喽 大佬,喝冰可乐! |
15
weivi 2022-04-28 09:18:18 +08:00
@Sunhcer 你说的这个文件常量池是记录在字节码文件中的,是保存于磁盘上的数据,类加载完成以后其实和 jvm 就没什么关系了。运行时常量池是根据这些文件上的数据,在内存里面形成的数据。我认为这俩本质上就是一个东西,只不过是同一种数据的两种形式而已,一种是磁盘中的形式,一种是主存中的形式。
|
16
Sunhcer OP @weivi 同一种来源的数据在不同阶段的不同呈现,这样说更准确; 来源上是一样,但数据不一样:打个比喻就像是,一个是带占位符的短信模板,一个是填充好的短信
|
17
weivi 2022-04-29 08:57:49 +08:00
@Sunhcer java 虚拟机规范关于运行时常量池介绍的第一句话。
------------------------------------------------------------------------------------- A run-time constant pool is a per-class or per-interface run-time representation of the constant_pool table in a class file (§4.4) |
18
Aresxue 2022-05-05 16:14:34 +08:00
目前每个 class 独立一个, 但官方有意图想做到一个 jar 中所有类共享一个常量池,至于全局一个可能有些弊大于利不是很说得准。
|