在堆栈内存中存储引用

时间:2015-04-21 14:02:21

标签: java

引用它自己如何存储在堆栈内存中。例如,假设,

A a = new A();

这个a也应该存储在内存中,并且应该有一个内存地址吗?

如果我解释更多,如果我们打印System.out.println(a),它将打印"对象A"的内存地址。但是如何打印引用a的内存地址?

更正:如果我们打印System.out.println(a),它将打印"对象A"的哈希码。不是对象A的内存地址

3 个答案:

答案 0 :(得分:1)

  

但是如何打印参考文件的内存地址?

你不能,非常简单。 JVM规范没有以任何方式定义堆栈的底层属性,并且严格遵守规范,不能保证它甚至具有内存地址。实际上,在当前的实现中,它确实如此,但是规范留下了未定义的,因此Java没有用于检查堆栈内存布局的接口。

此外,应该注意的是,事实上,堆栈变量根本不能保证具有存储器地址。他们完全驻留在寄存器中并且永远不会被刷新到内存中并不罕见。

但是,还应该提到的是,与您所说的不同,System.out.println(a)打印a引用的对象的地址。它的打印内容也未被规范定义,但Oracle的实现打印了a的身份哈希码,而不是其地址。 a的地址甚至不能保证在其生命周期内保持不变,因为GC可能会移动它。

答案 1 :(得分:0)

你的假设是错误的; System.out.println(a);将打印对象句柄的地址,而不是objcet本身:

  

在Oracle的一些Java虚拟机实现中,a   对类实例的引用是指向自身句柄的指针   一对指针:一对包含方法的表   object和指向Class对象的指针,表示类型   对象,另一个是从堆分配的内存   对象数据。

https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.7

由于JVM“保留在执行期间在内存中移动内容的权利”,因此无法保证对JVM对象本身的引用可用于任何事情。事实上,当Java执行垃圾收集时,它无法保证将转发指针放置到活动对象的新地址,这使得垃圾收集可能会呈现JVM地址(即使您可能获取它没用。

有关垃圾收集如何工作的简化说明,请参阅http://www.cs.cornell.edu/courses/cs312/2003fa/lectures/sec24.htm

答案 2 :(得分:0)

System.out.println(a)打印a.hashCode()(除非覆盖a.toString()),不必是a的地址。