2013-01-10 23 views
6

可能重複:
What exactly is null in Java memory如何在內存中表示空在java中

有誰知道一個空值是如何在對象或任何存儲表示。在網點中,它由空指示符布爾值和相應類型的值(Refer here)表示。那麼,任何人都知道它是如何在Java中完成的?

+2

你提到的問題是有點誤導 - 接受的答案是所有關於可空'',不爲空*引用*。 –

+0

檢查這個問題的接受的答案。將幫助你瞭解java中wt是空的.https://stackoverflow.com/questions/2707322/what-is-null-in-java –

回答

9

JVM specification, section 2.4

Java虛擬機規範並不強制一個具體值編碼爲空。

所以可能是任何東西,但它很可能是一個參考值是全零。引用本身可以是是簡單指針(即,與本機指針相同的虛擬地址,適用於架構的適當大小),但不一定非要。一些JVM具有處理引用的非常聰明的方式 - 例如,Hotspot是able to use 32-bit values for references in many situations, even when running in an x64 process

+0

」Java虛擬機規範不要求編碼爲null的具體值。「 < - 嗯,在這種情況下,它是如何{de,}序列化? – fge

+2

@fge:這是*內存*表示,它與序列化完全分離。 –

1

確切的表示形式沒有指定,但我會認爲它只是0x0就像它是在其他C類似的語言。這是一種特殊的價值,否則不會發生,而不是額外的領域或額外的信息。

注意:當你有一個String這是一個參考不是一個對象。這個4字節的值可以引用一個對象,或者在null的情況下是一個不是有效對象的值。

順便說一句:大多數64位JVM使用32位引用,除非堆是32 GB或更多。這在OpenJDK JVM中是可行的,因爲所有對象都是8字節(或16字節)對齊的。由於較低的3或4位始終爲0,因此無需存儲,即可將地址範圍擴展8倍或16倍(典型4 GB範圍)。

+0

@HannesHertach我已經添加了一個解釋爲爲什麼32 GB可以通過32位參考尋址。 「 –

1

應該爲null本身分配內存,因爲null實際上不是有效的對象實例。它只是一個佔位符,指示對象引用當前不引用對象。

當你做這樣的事情:

字符串str = NULL;

分配的唯一東西是對字符串的引用(這類似於包含指針類型的語言中的字符串指針)。該引用是駐留在堆棧上的32位或64位變量(取決於您的硬件架構和Java版本)(可能取決於聲明的確切上下文)。

+0

什麼是你的概念的參考?只是抽象數字? – Andremoniy

1

理論上它是一個JVM祕密,實際上它是32位虛擬機上的0(0x00000000)。如果使用Oracle JVM,則可以使用sun.misc.Unsafe(可以在任何地址讀取內存內容)進行驗證。

public class Test { 
    int i1 = 100; 
    String s = null; 
    int i2 = 200; 

    public static void main(String[] args) throws Exception { 
     Test test = new Test(); 
     System.out.println(getInt(test, "i1")); 
     System.out.println(getInt(test, "s")); 
     System.out.println(getInt(test, "i2")); 
    } 

    static int getInt(Test test, String name) throws Exception { 
     Unsafe u = getUnsafe(); 
     long offset = u.objectFieldOffset(Test.class.getDeclaredField(name)); 
     return u.getInt(test, offset); 
    } 

    static Unsafe getUnsafe() throws Exception { 
     Field f = Unsafe.class.getDeclaredField("theUnsafe"); 
     f.setAccessible(true); 
     return (Unsafe) f.get(null); 
    } 
} 

輸出

100 
0 
200 
+0

這隻能證明當試圖讀取一個空引用爲int時,Unsafe(最終)會返回零。並且還要考慮getInt的文檔部分「...但是,如果該變量實際上不是此方法返回的類型,結果是未定義的......」 –