2015-04-21 135 views
1

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

A a = new A(); 

a也应存放在内存,并应该有一个内存地址吗?

如果我解释更多,如果我们打印System.out.println(a)它将打印“对象A”的内存地址。但是,我怎样才能打印参考a的内存地址?

更正:如果我们打印System.out.println(a)将打印的“物体A”对象的不是内存地址A

回答

1

但是我怎样才能打印参考a的内存地址?

你不能,很简单。 JVM规范没有以任何方式定义堆栈的基本属性,严格按照规范进行定义,但不保证它甚至有内存地址。实际上,在当前的实现中,当然是这样,但规范保留了未定义的规则,因此Java没有用于检查堆栈内存布局的接口。

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

但是,也应该提到的是,不像你说的话,System.out.println(a)打印对象的地址通过a简称。它所打印的内容也没有被规范定义,但是Oracle的实现打印了a的身份哈希码,而不是它的地址。地址a甚至不能保证在其整个生命周期内保持不变,因为GC可能会移动它。

+0

纠正其“a”的哈希码 – Harshana

0

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

在某些Java虚拟机的Oracle的实现,一个 引用一个类的实例是一个指向一个句柄,其本身 一对指针:一个表包含对象的方法和一个指向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了解垃圾收集如何工作的简单说明。

+0

我不明白“对象的句柄的地址”的含义。正如你所提到的“a”cosider作为指针,它自己应该存储在内存中的指针知道。我所理解的是指针“a”具有作为对象A的哈希码的值。 – Harshana

+0

已更新的答案。 – EvenLisle

0

System.out.println(a)打印a.hashCode()(除非a.toString()被重写),它不一定是a的地址。