java - 编译器生成的相对地址以及它们如何在(最好是 java)字节码中表示?

标签 java memory-management compiler-construction bytecode relative-addressing

如果地址绑定(bind)在编译时是不可能的,它会在加载/链接或运行时完成,将相对(或者我们可以称它们为可重定位地址)地址与实际物理地址相关联。此外,CPU 还会在绑定(bind)物理地址之前将这些相对地址转换为逻辑地址。

从逻辑到物理的转换对我来说是一个众所周知的概念。但是,我对那些相对寻址感到困惑(AFAIK,他们之所以称之为相对是因为它们是由编译器相对于零给出/分配的)。我不确定什么相对地址用于(在字节码中)或者是否真的需要它们,或者它们甚至与逻辑地址相同?

最佳答案

你混淆了很多概念。相对地址只是需要将基地址转换为绝对地址的地址。这种转变可以通过多种方式发生。 一种方法是在加载时转换它们,但它们也可以与 CPU 指令一起使用,CPU 指令本质上支持相对寻址,在需要访问内存位置时正确地进行数学运算。

如果操作系统支持虚拟内存,则普通进程中使用的所有地址都是逻辑地址,无论它们是相对引用还是绝对引用。从逻辑地址到物理地址的转换超出了应用程序的范围,并且独立于您在问题中提到的任何其他概念。

类文件格式不根据内存位置进行操作。

如果您想在更高级别上应用术语“绝对”和“相对”,常量池索引是绝对,因为它们不需要基本索引来标识实际索引。尽管如此,当你想在加载的文件中找到内存位置时,你不仅必须使用类文件加载到的地址,你还必须解析整个常量池直到所需的项目,因为常量池有不同的字节大小。因此,通常根本不会查找项目。取而代之的是,整个池在单次传递中被转换为具有恒定项目大小的 JVM 特定表示,稍后,JVM 可能会查找该表的条目,而这与类文件的内存位置无关。

在字节码指令中,使用了相对偏移量,这需要添加当前指令的位置以获得绝对位置,但请注意这不符合您问题中提到的概念。绝对位置仍然是指令序列中的位置,因此,在谈论地址时,相对于代码的内存位置。此外,不使用相对偏移量,因为“在编译时不可能绑定(bind)”,由此产生的绝对位置在编译时是已知的。 Java 字节码指令集只是定义为使用相对偏移量以允许更紧凑的代码。从指令集的角度来看,我们可以说它本质上支持相对寻址。 JVM 如何实际实现其执行,取决于 JVM。

you mentioned the JVM’s native code generation ,当 JVM 生成 native 代码时,它知道代码的目标地址,并且可以根据需要自由决定使用相对地址还是绝对地址。

如前所述,上面描述的一切都发生在一个进程中,因此如果操作系统使用虚拟内存,则都是根据操作系统可能调整的逻辑地址,例如通过 MMU。这些概念是不相关的。

关于java - 编译器生成的相对地址以及它们如何在(最好是 java)字节码中表示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38977662/

相关文章:

java - 将值绑定(bind)到 Guice 中的两种可能性之一

python - 即使在 gc.collect() 之后,分配给 Python 的内存也不会在 Linux 中释放回来

c - 为什么这个程序不创建核心转储?

c++ - Visual Studio 将 "filter"编译为 C,将 "filters"组编译为 C++

java - 当我运行一个单线程 Java 程序时,为什么在操作系统级别有多个线程?

java - 为什么我的 FPS 下降?

c++ - 为什么函数中本地定义的结构需要赋值运算符和复制构造函数

c - 整数和长整数的大小?

java - 用图像网格填充屏幕的最佳方法

delphi - TInterfacedObject 自动内存管理也可以与 C++Builder 一起使用吗?