簡體   English   中英

Java - 空變量是否需要內存空間

[英]Java - Does null variable require space in memory

考慮以下代碼塊:

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值在內存中占用多少內存? (例如int需要 4 個字節)。

Q2。 一個字符串在內存中占用多少空間? 一個字符串占用多少內存空間? 它取決於字符串的長度嗎?

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

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

我想補充:

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

    對象 s = (String)null;

    對象 i = (Integer)null;

    System.out.println(s == i);//真

您可以使用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

與自動壓縮 oops 關閉相同:

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 )。 (如果你有多個實例,這取決於你多次使用相同的還是不同的)。 內存中不能跳過空字段,因為它需要在分配實例時調整其大小。 所以這些字段都是預先構造的,它們只是不引用堆上其他地方的分配對象。

注意:如果您實現默認構造函數,您將獲得更多詳細信息,但在這種特定情況下,大小將是相同的。 如果你想知道字段的序列和填充來自哪里,你可以查看這篇文章-(基本上它在 8 個字節上對齊對象,按大小對字段排序,將相同類型組合在一起,最后引用。來自超級類型的字段是第一, 4 字節對齊。)

Null 表示 0。通常在內存中定義一個地方為 null。 每當有人使用編程語言指向它時。 一切都指向同一個地方。 這意味着 NULL 只消耗 1 個 4 字節的內存。 然后任何指向它的東西都不會消耗更多的內存。 NULL 的定義是特定於語言的,但將其定義為 void *ptr=0; 在 C 和 C++ 中很常見。 JAVA 肯定也有類似的定義。 不可能指向任何東西 ofc。 你必須指出一些東西。 但是我們定義了一個共同的虛無,所有指向它的東西都只消耗那個空間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM