2010-03-12 20 views
52
class CheckStore { 
    private String displayText; 
    private boolean state; 
    private String meaningfulText; 
    private URL url; 

    public CheckStore(String text, boolean state) { 
     this.displayText = text; 
     this.state = state; 
    } 
    : 
    : 
} 

由於我初始化只有兩個在構造函數變量(displayTextstate),將剩下的兩個變量(meaningfulTexturl這將對價值null)將需要空間在內存中存儲null的值。爪哇 - 是否空變量需要的內存空間

Q1。我認爲他們需要空間。如果他們願意,那麼內存中的值會佔用多少內存(如int需要4個字節)。 Q2302。一個字符串在內存中佔用多少空間。我想這將取決於字符串的長度。那麼一個字符串需要多少空間才能達到多少長度?

回答

47

在Java中,null只是一個引用(它基本上是一個受限指針)可以擁有的值。這意味着參考文獻沒有涉及任何內容。在這種情況下,您仍然佔用參考空間。這是32位系統上的4個字節或64位系統上的8個字節。但是,除非實際分配該類的實例以指向引用,否則不會佔用該引用指向的類的任何空間。

編輯:就字符串而言,Java中的String需要16位(2個字節)用於每個字符,再加上少量的簿記開銷,這可能是未記錄的和實現特定的。

+0

請你也請告訴我爲什麼需要差異。 64位和32位系統上的空間? – 2010-03-12 05:28:28

+1

@Yatendra:指針必須足夠大才能跨越整個地址空間。因此,在32位機器上,你需要32位。在64位機器上,你需要64位。 – dsimcha 2010-03-12 05:29:57

+10

不一定......在HotSpot中有一些有趣的工作可以避免這種情況:http://wikis.sun.com/display/HotSpotInternals/CompressedOops – 2010-03-12 06:28:58

9

我想添加:

  1. 引用類型的變量將作爲空值被初始化。
  2. null不是對象。因爲(null instanceof Object)等於假
  3. JVM中只有一個空值。不管有多少變量引用null。

    Object s =(String)null;

    對象i =(整數)null;

    的System.out.println(S == I); //真

+0

1. *成員*引用類型的變量被初始化爲null。局部變量不是。 2. Null不是'Object',不是因爲'null instanceof Object'爲false,而是因爲null是引用。 3.在JVM中有很多空值是由(a)'aconst_null'操作碼(b)成員變量初始化(c)等創建的。語句沒有意義。 'null'總是等於它自己,但這並不意味着任何關於身份的東西。 – EJP 2017-02-09 23:05:47

2

您可以使用jol來獲取類的佈局。 (但要小心,您可能需要對其背後的機制有更深入的瞭解,不要盲目信任結果,並且意識到它僅僅是對當前使用的VM的估計(在我的情況下爲1.7.0_76 x64勝利:):

我使用CLI版本我想正確的方法是在您的項目庫中,但無論如何,它似乎以這種方式工作:

test>java -cp target\classes;jol-cli-0.3.1-full.jar org.openjdk.jol.Main internals test.CheckStore 
Running 64-bit HotSpot VM. 
Using compressed oop with 0-bit shift. 
Using compressed klass with 0-bit shift. 
Objects are 8 bytes aligned. 
Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] 
Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] 

VM fails to invoke the default constructor, falling back to class-only introspection. 

test.CheckStore object internals: 
OFFSET SIZE TYPE DESCRIPTION     VALUE 
     0 12   (object header)    N/A 
    12  1 boolean CheckStore.state    N/A 
    13  3   (alignment/padding gap)  N/A 
    16  4 String CheckStore.displayText   N/A 
    20  4 String CheckStore.meaningfulText  N/A 
    24  4  URL CheckStore.url     N/A 
    28  4   (loss due to the next object alignment) 
Instance size: 32 bytes (estimated, the sample instance is not available) 
Space losses: 3 bytes internal + 4 bytes external = 7 bytes total 

並具有自動壓縮哎呀關閉相同:

test>java -XX:-UseCompressedOops -cp target\classes;jol-cli-0.3.1-full.jar org.openjdk.jol.Main internals test.CheckStore 
Running 64-bit HotSpot VM. 
Objects are 8 bytes aligned. 
Field sizes by type: 8, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] 
Array element sizes: 8, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] 

VM fails to invoke the default constructor, falling back to class-only introspection. 

test.CheckStore object internals: 
OFFSET SIZE TYPE DESCRIPTION     VALUE 
     0 16   (object header)    N/A 
    16  1 boolean CheckStore.state    N/A 
    17  7   (alignment/padding gap)  N/A 
    24  8 String CheckStore.displayText   N/A 
    32  8 String CheckStore.meaningfulText  N/A 
    40  8  URL CheckStore.url     N/A 
Instance size: 48 bytes (estimated, the sample instance is not available) 
Space losses: 7 bytes internal + 0 bytes external = 7 bytes total 

這些只是對象本身的佈局如果您的字段爲空,則它不會指向更多的對象,否則您必須查看目標類型(URLString)。 (如果你有多個實例的話,這取決於你使用相同的多次還是不同的次數)。空字段不能在內存中跳過,因爲它需要實例在分配時調整大小。所以這些字段都是預先構建的,它們只是不會在堆上的其他地方引用分配的對象。

注意:如果你實現了一個默認的構造函數,你會得到更多的細節,但在這個特定情況下的尺寸是相同的。如果你想知道字段序列和填充是從哪裏來的,你可以檢查this article - (基本上它將8個字節的對象對齊,按大小對字段進行排序,將相同類型組合在一起,引用最後一個字段。字節對齊。)