如何自引用是否存儲在堆棧內存中。例如,假設,在堆棧內存中存儲引用
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