我已经读过the following stackoverflow question,但仍然有几个不清楚的问题。
假设我具有以下java类:
class Main {
public static void main(String[] args) {
String str = "hello";
}
}
编译Main.java文件时,对变量和方法的所有引用都作为符号引用存储在类的常量池中(存储在Main.class文件内部)。符号引用是逻辑引用,而不是实际上指向物理内存位置的引用。
类常量池将具有代表{hello”字符串文字的Utf8条目。
Constant pool:
#1 = Methodref #4.#13 // java/lang/Object."<init>":()V
#2 = String #14 // hello
#3 = Class #15 // Main
#4 = Class #16 // java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Utf8 Code
#8 = Utf8 LineNumberTable
#9 = Utf8 main
#10 = Utf8 ([Ljava/lang/String;)V
#11 = Utf8 SourceFile
#12 = Utf8 Main.java
#13 = NameAndType #5:#6 // "<init>":()V
#14 = Utf8 hello /////// CONSTANT_Utf8_info entry ///////
#15 = Utf8 Main
#16 = Utf8 java/lang/Object
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=2, args_size=1
0: ldc #2 // String hello
2: astore_1
3: return
LineNumberTable:
line 3: 0
line 4: 3
请注意#14常量池条目。
当JVM加载并链接Main.class文件时,它将在方法区域中的堆上为此类创建运行时类常量池(我想这是来自.class的类常量池的对象表示)文件)。对于.class文件中的Utf8条目,JVM在链接过程中创建了CONSTANT_Utf8_info对象。
根据规范,CONSTANT_Utf8_info对象包含代表“ hello”字符串的bytes数组。这个字节数组是在运行时类常量池,字符串池中还是在堆的Young Generation空间中分配的吗?
字符串池数据结构的深度如何?它是否包含对运行时类常量池中的字符串文字的引用,还是表示字符串文字的哈希表/数组?
根据the following文章“字符串池”被认为是Hashtable<oop, Symbol>
,但尚不清楚什么是oop和Symbol以及它们表示什么数据结构。
您能解释一下当JVM从上面的字节码执行“ ldc#2”行时,它在内部发生了什么(如何分配内存以及在什么空间,什么在栈中)。
您能说“ hello”字符串文字何时可用于GC吗?
如果您在回答此问题时留下一些到官方JVM规范的链接并提供一些证明,我将不胜感激。