繁体   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