是否在类常量池,字符串池或年轻代中分配字符串文字的空间? GC何时可以访问字符串文字?

时间:2018-07-12 23:56:27

标签: java string memory memory-management heap-memory

我已经读过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规范的链接并提供一些证明,我将不胜感激。

0 个答案:

没有答案