如何自引用是否存储在堆栈内存中。例如,假设,在堆栈内存中存储引用
A a = new A();
这a
也应存放在内存,并应该有一个内存地址吗?
如果我解释更多,如果我们打印System.out.println(a)
它将打印“对象A”的内存地址。但是,我怎样才能打印参考a
的内存地址?
更正:如果我们打印System.out.println(a)
将打印的“物体A”对象的不是内存地址A
如何自引用是否存储在堆栈内存中。例如,假设,在堆栈内存中存储引用
A a = new A();
这a
也应存放在内存,并应该有一个内存地址吗?
如果我解释更多,如果我们打印System.out.println(a)
它将打印“对象A”的内存地址。但是,我怎样才能打印参考a
的内存地址?
更正:如果我们打印System.out.println(a)
将打印的“物体A”对象的不是内存地址A
但是我怎样才能打印参考a的内存地址?
你不能,很简单。 JVM规范没有以任何方式定义堆栈的基本属性,严格按照规范进行定义,但不保证它甚至有内存地址。实际上,在当前的实现中,当然是这样,但规范保留了未定义的规则,因此Java没有用于检查堆栈内存布局的接口。
此外,应该注意的是,实际上,堆栈变量根本不能保证有内存地址。它们完全驻留在寄存器中并且不会被刷新到内存中并不罕见。
但是,也应该提到的是,不像你说的话,System.out.println(a)
将不打印对象的地址通过a
简称。它所打印的内容也没有被规范定义,但是Oracle的实现打印了a
的身份哈希码,而不是它的地址。地址a
甚至不能保证在其整个生命周期内保持不变,因为GC可能会移动它。
你的假设是错误的哈希码; 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了解垃圾收集如何工作的简单说明。
System.out.println(a)
打印a.hashCode()
(除非a.toString()
被重写),它不一定是a的地址。
纠正其“a”的哈希码 – Harshana