当在编译时无法进行地址绑定时,它在加载/链接或运行时完成,以将相对(或者我们可以称之为可重定位地址)地址与实际物理地址相关联。此外,在绑定物理地址之前,CPU还会将这些相对地址转换为逻辑地址。
从逻辑转换为物理对我来说是一个众所周知的概念。但是,我对这些相对寻址感到困惑(AFAIK,他们称之为亲戚,因为他们被编译器给予/分配相对于零)。我不确定相关地址是用于(在字节码中)还是真的需要它们,或者它们甚至与逻辑地址相同?
答案 0 :(得分:1)
Java字节码在比本机机器代码高得多的抽象级别上运行。根本没有内存地址的概念 - 方法被象征性地引用。
考虑Java字节码的最简单方法是使用Java语言的初始版本实际上是1:1。编译器做了一些事情,比如将局部变量转换为数字索引并将控制流转换为gotos,但在大多数情况下,它与原始代码非常相似。
JVM负责在运行时将字节码解释或编译为本机代码。
答案 1 :(得分:1)
获取对象的内存地址在Java中实际上毫无意义:因为JVM正在管理所有这些。
换句话说:JVM" put"对象应该在哪里适合;它们甚至可以被移动"周围;例如在垃圾收集期间。
换句话说:作为Java程序员,你不在乎。如果你愿意的话你无能为力。
答案 2 :(得分:1)
你混淆了很多概念。相对地址只是需要将基地址转换为绝对地址的地址。转换可以在很多方面发生。 一种方式是在加载时转换它们,但它们也可以只与CPU指令一起使用,当需要访问内存位置时,它本质上支持相对寻址进行数学运算。
如果操作系统支持虚拟内存,则普通进程中使用的所有地址都是逻辑内存,无论它们是相对引用还是绝对引用。从逻辑地址到物理地址的转换超出了应用程序的范围,并且独立于您在问题中提到的任何其他概念。
类文件格式不按内存位置运行。
如果要在更高级别应用术语“绝对”和“相对”,则常量池索引绝对,因为它们不需要基本索引来标识实际索引。仍然,当您想要在加载的文件中找到内存位置时,您不仅必须使用加载类文件的地址,还必须将整个常量池解析为所需的项,因为常量池具有不同的字节大小。因此,通常不会查看项目。相反,整个池在一次传递中转换为具有常量项大小的JVM特定表示,稍后,JVM可能会查找该表的条目,而不依赖于类文件的内存位置。
在字节代码指令中,使用相对偏移,这需要添加当前指令的位置以获得绝对位置,但请注意这不适合您的问题中指定的概念。绝对位置仍然是指令序列内的位置,因此,当谈论地址时,相对于代码的存储位置。此外,由于“在编译时不可能进行绑定”,因此不使用相对偏移,所得到的绝对位置在编译时是已知的。 Java字节代码指令集刚刚被定义为使用相对偏移来允许更紧凑的代码。从指令集的角度来看,我们可以说它本质上支持相对寻址。 JVM实际上如何实现其执行取决于JVM。
从you mentioned the JVM’s native code generation开始,当JVM生成本机代码时,它知道代码的目标地址,并且可以自由决定使用相对或绝对地址,就像它适合一样。
如上所述,上述所有内容都发生在一个进程中,因此如果操作系统使用虚拟内存,则所有操作系统都可以根据操作系统进行调整,例如:通过MMU。这些概念是无关的。