xea*_*xea 6 java jvm constants .class-file
在Java虚拟机规范规定,8字节(如long和double)常量占用两个条目在constant_pool表中,不同于占用每个只有一个入口其他常量.该规范还提到它是一个糟糕的选择,但没有解释原因.
这个设计决定背后的原因是什么?当时的好处是什么?
一个明确的答案需要与参与 Java 早期开发的人员交谈。然而,我认为很明显,字节码格式最初设计时考虑的是简单解释器的性能。
考虑一下如何编写一个非常简单的 Java 字节码解释器。没有 JIT,没有优化等。您只需执行每条指令即可。假设常量池在加载时已被解码为 32 位值的表,像 ldc2_w x 这样引用常量池的指令将沿着以下行执行 C 代码
*(*int64)(stack_ptr += 8) = *(*int64)(constant_pool_ptr + x * 4)
基本上,如果您使用的是 32 位计算机,并且将所有内容转换为原始指针访问而不进行优化,那么使用两个插槽来存储 64 位值就是实现事物的逻辑方法。
今天它是一个糟糕的选择,因为现在的口译员并没有像这样完全没有优化。事实上,代码通常是 JIT 的。此外,64 位平台是常态,这意味着引用类型无论如何都会占用 64 位*,即使规范将它们视为 32 位值。因此,这种黑客行为不再有任何好处,但我们仍然付出规范和实现复杂性的代价。
^ 至少理论上是这样。即使在 64 位平台上,JVM 默认也使用 32 位压缩指针,以减少内存使用。