Java Constant Pool的目的是什么?

Bob*_*r02 65 java class-constants vm-implementation

我目前正在尝试深入研究Java虚拟机的规范.我一直在网上阅读JVM内容,有一个令人困惑的抽象,我似乎无法理解:Constant Pool.这是本书的摘录:

对于它加载的每种类型,Java虚拟机必须存储常量池.常量池是类型使用的有序常量集,包括文字(字符串,整数和浮点常量)以及对类型,字段和方法的符号引用.常量池中的条目由索引引用,非常类似于数组的元素.因为它包含对类型使用的所有类型,字段和方法的符号引用,所以常量池在Java程序的动态链接中起着核心作用

关于上述内容和CP,我有几个问题:

  1. CP是否位于.class每种类型的文件中?
  2. 作者的"象征性参考"是什么意思?
  3. 什么是Constant Pool的目的,用简单的英语?

axt*_*avt 80

常量池是.class文件(及其内存中表示)的一部分,它包含运行该类代码所需的常量.

这些常量包括程序员指定的文字和编译器生成的符号引用.符号引用基本上是从代码引用的类,方法和字段的名称.JVM使用这些引用将您的代码链接到它依赖的其他类.

例如,以下代码

System.out.println("Hello, world!");
Run Code Online (Sandbox Code Playgroud)

产生以下字节码(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
Run Code Online (Sandbox Code Playgroud)

#n这里是对常量池的引用.#2System.out字段的符号引用,#3是一个Hello, world!字符串,#4PrintStream.println(String)方法的符号引用.

如您所见,符号引用不仅仅是名称 - 例如,对该方法的符号引用还包含有关其参数(Ljava/lang/String;)和返回类型(V均值void)的信息.

您可以通过运行该类来检查类的常量池javap -verbose.

  • JVM基本上只创建了一个运行时常量池吗?或者每个.class文件都有一个单独的常量池吗? (2认同)
  • 每个类文件中都有一个常量池.它由编译器创建.JVM在运行时解析CP的引用.字符串实习池是VM内的一个区域. (2认同)

Jam*_*ard 67

我认为理解如何使用图表构建框架会有所帮助.

在此输入图像描述

帧是操作数(操作指令)所在的位置,也就是动态链接发生的位置.这是一种速记方式,可以说,使用常量池来跟踪班级及其成员.

每个帧都包含对运行时常量池的引用.该引用指向正在为该帧执行的方法的类的常量池.此参考有助于支持动态链接.

通常将C/C++代码编译为目标文件,然后将多个目标文件链接在一起以产生可用的工件,例如可执行文件或dll.在链接阶段期间,每个目标文件中的符号引用被替换为相对于最终可执行文件的实际存储器地址.在Java中,此链接阶段在运行时动态完成.

编译Java文件时,对变量和方法的所有引用都存储在类的常量池中作为符号引用.符号引用是逻辑引用,而不是实际指向物理内存位置的引用.

以下是James Blooms JVM Internals的链接,了解更多详情.


Pet*_*Mmm 9

什么是Constant Pool的目的,用简单的英语?

CP是一个存储区域,存储非常独特的常量值以减少冗余:

System.err.println("Hello");
System.out.println("Hello");
Run Code Online (Sandbox Code Playgroud)

在CP中,只有一个String对象"Hello",编译器将两行替换为相同的引用.您的.class文件只包含一个Hello字符串.(其他类型也一样).

CP是否位于每种类型的.Class文件中?

是的,请看这里:http://en.wikipedia.org/wiki/Java_class_file