2011-03-18 40 views

回答

4

這是因爲引用變量實際上並不包含對象。這是達到目標的一種方式。 JVM管理這種方式是我們最不關心的事情。您可以將其視爲堆中對象位置的地址。但它不必像地址那樣直截了當。

+0

事實上,它可能不能,因爲GC在物理內存中移動對象很多,所以JVM需要額外的間接級來保持引用是最新的。 – 2011-03-18 11:06:12

0

8 Bytes是Java中Long變量的大小,允許引用1.01457092×10^19個引用,這對大多數應用程序來說應該足夠了,並且比大多數硬盤驅動器可以解決的問題要大,因爲考慮到每個引用點需要還擁有數據...

編輯: 看了我想澄清的是,引用只是一個指針數據其他答案之一,不包含數據,在Java架構師決定使用64位值來表示引用,因爲它給你一個巨大的地址空間。

9

其實,這是行不通指定的參考變量應該有多少個字節有,事實上,它不是到處都一樣。

用於32位系統(即內存總線中具有32位地址的系統)的通用虛擬機通常使用32位(= 4字節,與intfloat相同)作爲對象引用的大小,而虛擬機對於64位系統,通常使用64位本地地址(= 8字節)。 (請注意,大多數64位系統也可以運行32位程序,因此即使在那裏您也會使用32位虛擬機。)

這只是簡化實現的問題,如果您可以使用實際的內存地址爲您的引用,而不是別的。

因爲這增加了使用的內存大小(通常,我們實際上並不需要訪問的內存),from Java 7 on 64位HotSpot虛擬機將能夠使用在一定條件下的32位參考,即當堆小於32 GB時(8·2 字節)。要將它們轉換爲實際的內存地址,它們會乘以8(因爲對象將在8字節邊界上對齊),然後添加到基址(如果不爲零)。 (對於小於4 GB的堆,我們不需要乘法步驟。)

其他虛擬機可能使用類似的技巧。

+0

64位JVM不一定使用64位引用。例如,熱點默認使用32位。 – assylias 2013-07-23 15:26:43

+0

感謝您的糾正......您是否有鏈接到相關文檔? – 2013-07-24 07:38:26

+0

http://stackoverflow.com/a/17814352/829571包含鏈接 – assylias 2013-07-24 09:50:30

2

讓我舉個例子,以幫助您更好地瞭解

String myName = new String("John"); 
    String yourName = new String("John"); 
    if (myName == yourName) 
    { 
     System.out.println("Refereces point to Same objects on heap"); 
    } else 
    { 
     System.out.println("Refereces point to different objects on heap"); 
    } 

和輸出Refereces指向不同的對象上堆

這裏MYNAMEYOURNAME是兩個引用其指向類型字符串(上堆分配存儲器)的對象。註釋參考變量的內存分配在堆棧上,而不是在堆上。兩個引用變量都只有位於堆上的String對象的地址(或類似的唯一抽象)。地址的大小對於特定的操作系統體系結構將保持不變。在32位的情況下,它將是4個字節,而對於64位,它將是8個字節。

所以指出的對象的大小是尊敬變量可能會改變,但引用的大小保持不變,因爲它們只是攜帶對任何特定體系結構保持不變的地址。