我研究过 JVM(尤其是 JDK 8 版本)并且在研究类链接时,我还没有弄清楚从解析中的符号引用确定的直接内存地址在哪里。
解析有好几种,例如类型(类/接口)、字段、方法等,但我只是做了一个类的例子来简单说明。
在JVM规范中,有一些话。
5.1 运行时常量池 Java 虚拟机维护每个类型的常量池(第 2.5.5 节),这是一种运行时数据结构,可用于传统编程语言实现的符号表的许多目的。类或接口的二进制表示形式的 constant_pool 表(第 4.4 节)用于在类或接口创建时(第 5.3 节)构建运行时常量池。运行时常量池中的所有引用最初都是象征性的。
规范说,所有引用最初都是符号引用。
这是一个示例 Main 类。
public class Main {
public static void main(String[] args) {
Object obj = new Object();
}
}
这是 Main 类的常量池信息。
Constant pool:
#1 = Methodref #2.#12 // java/lang/Object."<init>":()V
#2 = Class #13 // java/lang/Object
#3 = Class #14 // Main
#4 = Utf8 <init>
#5 = Utf8 ()V
#6 = Utf8 Code
#7 = Utf8 LineNumberTable
#8 = Utf8 main
#9 = Utf8 ([Ljava/lang/String;)V
#10 = Utf8 SourceFile
#11 = Utf8 Main.java
#12 = NameAndType #4:#5 // "<init>":()V
#13 = Utf8 java/lang/Object
#14 = Utf8 Main
{
public Main();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: new #2 // class java/lang/Object
3: dup
4: invokespecial #1 // Method java/lang/Object."<init>":()V
7: astore_1
8: return
LineNumberTable:
line 3: 0
line 4: 8
}
SourceFile: "Main.java"
4.4.1 CONSTANT_Class_info 结构
CONSTANT_Class_info 结构用于表示一个类或一个 > 接口:
CONSTANT_Class_info {
u1 tag;
u2 名称索引;
}
这里,Object 类在 Main 类的 main 方法中被引用。在 Main 类中,从不引用 Object 类。(当命令java Main
刚刚执行时;)这意味着Object Class entry(here, #2: CONSTANT_Class_info structure.)
在 Main 的常量池中有 name_index #13。#13 是包含 Object 类名称的 CONSTANT_Utf8_info 结构,#13 是 Object 类的符号引用。(老实说,我可能不确定这个 Utf8 常量池条目是 #2(Object 的类池条目)的符号引用)
当 JVM 的执行引擎只执行一个字节码,该字节码具有 Object 类的引用(在这个类中,0: new #2
),#2 引用 #13(符号引用)。所以,需要解析为JVM中Method Area上Object Class的直接地址。并且发生类解析。
这是问题。 我已经阅读并搜索了 JVM 规范、博客、文章,但我找不到 JVM 中符号引用存储的已解析直接内存地址在哪里。
我在博客中找到了一些信息,它说,
绑定是由符号引用标识的字段、方法或类被直接引用替换的过程,这只会发生一次,因为符号引用被完全替换了。
说,换了。在#2 常量池条目中,Object 类的符号引用存储在 CONSTANT_Class_info 结构的 name_index(u2 type) 字段中。
name_index 字段的值是否更改为对象类的直接内存地址(可能在方法区中对象 clsas 的运行时常量池中)????
如果没有,直接地址存储在哪里?
请给我答案。谢谢你。