目前,我正试图深入研究Java虚拟机的规范。我一直在阅读Inside the JVM book online,有一个我似乎无法理解的令人困惑的抽象:常量池。以下是这本书的摘录:
对于所加载的每种类型,
虚拟机必须存储一个常量池。常量池是类型使用的一组有序常量,包括文字(字符串、整数和浮点常量)和对类型、字段和方法的符号引用。常量池中的条目由索引引用,非常类似于数组的元素。因为它包含对类型所使用的所有类型、字段和方法的符号引用,所以常量池在Java程序的动态链接中起着核心作用。
我有几个问题,关于以上和CP的一般:
.class文件中的每一种类型?。
发布于 2013-12-03 17:24:19
我认为理解如何使用图表构造框架会有所帮助。

框架是操作数(操作指令)驻留的地方,也是动态链接发生的地方。可以说,这是一种速记的方式,使用常量池来跟踪类及其成员。
每个框架包含对运行时常量池的引用。引用指向为该帧执行的方法的类的常量池。此引用有助于支持动态链接。
C/C++代码通常被编译到一个对象文件中,然后将多个对象文件链接在一起产生一个可用的工件,如可执行文件或dll。在链接阶段,每个对象文件中的符号引用被替换为相对于最终可执行文件的实际内存地址。在Java中,这个链接阶段是在运行时动态完成的。
编译Java文件时,对变量和方法的所有引用都作为符号引用存储在类的常量池中。符号引用是逻辑引用,而不是实际指向物理内存位置的引用。
下面是James Blooms JVM Internals的一个链接,以了解更多细节。
发布于 2012-04-18 13:25:33
常量池是.class文件(及其内存中的表示)的一部分,它包含运行该类代码所需的常量。
这些常量包括程序员指定的文字和编译器生成的符号引用。符号引用基本上是代码中引用的类、方法和字段的名称。JVM使用这些引用将代码链接到它所依赖的其他类。
例如,下面的代码
System.out.println("Hello, world!");生成以下字节码(javap输出)
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3; //String Hello, world!
5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V#n这里是对常量池的引用。#2是对System.out字段的符号引用,#3是Hello, world!字符串,#4是对PrintStream.println(String)方法的符号引用。
如您所见,符号引用不仅仅是名称--例如,对方法的符号引用还包含有关其参数(Ljava/lang/String;)和返回类型(V意为void)的信息。
可以通过为类运行javap -verbose来检查该类的常量池。
发布于 2012-04-18 13:15:23
用简单的英语来说,常数池的目的是什么?
CP是一个内存区域,非常独特的常量值被存储以减少冗余:
System.err.println("Hello");
System.out.println("Hello");在CP中,只有一个字符串对象"Hello“,编译器在这两行中替换为相同的引用。您的.class文件只包含一个Hello字符串。(其他类型相同)。
是否每种类型的CP都位于.Class文件中?
是的,看这里:http://en.wikipedia.org/wiki/Java_class_file
https://stackoverflow.com/questions/10209952
复制相似问题