java - 是在 Class Constant Pool、String Pool 还是 Young Generation 中分配字符串文字的空间?GC 何时可以访问字符串文字?
问题描述
我已阅读以下 stackoverflow 问题,但仍有几个问题不清楚。
假设我有以下 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”字符串的字节数组。这个字节数组是分配在运行时类常量池、字符串池还是堆的年轻代空间内?
字符串池数据结构的深度如何?它是否包含对来自运行时类常量池的字符串文字的引用或表示字符串文字的哈希表/数组?
根据下面的文章 String Pool 被认为是一个Hashtable<oop, Symbol>
但不清楚什么是 oop 和 Symbol 以及它们代表什么数据结构。
你能解释一下当 JVM 从上面的字节码执行“ldc #2”行时在内部发生了什么(内存是如何分配的,在什么空间中,堆栈上有什么)。
你能说 GC 何时可以访问“hello”字符串文字吗?
如果您在回答这个问题时留下一些指向官方 JVM 规范的链接以及一些证据,我将不胜感激。
解决方案
推荐阅读
- php - 从数字开始对字符串数组进行排序
- python - 如何在 Django 2.0 中处理 django-subdomains
- python - 没有急切执行的张量流中的反复损失
- wordpress - Wordpress:查询事件
- snowflake-cloud-data-platform - 是否可以一次获取几个表的列?
- c# - Unity2D:播放器与对象发生碰撞时显示消息
- clojure - Clojure 列表理解 - 在某些情况下只运行一次内部循环?
- php - PHP按时间顺序将存储数组中的值设置为嵌套的foreach循环
- javafx - JavaFX 虚拟键盘与文本字段组件重叠
- highcharts - 如何在highcharts中获取轴列刻度的高度