代码之家  ›  专栏  ›  技术社区  ›  Amit

Java-空变量需要内存空间吗?

  •  60
  • Amit  · 技术社区  · 15 年前
    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;
        }
        :
        :
    }
    

    因为我只初始化两个变量( displayText state )在构造函数中,其余两个变量( meaningfulText url 有价值的 null )将需要内存空间来存储 无效的 价值。

    Q1。我想他们需要空间。如果他们愿意的话,那么一个 无效的 值接受内存(例如 int 需要4个字节)。

    Q2。一个字符串占用内存的空间。我想这取决于绳子的长度。那么一个字符串的长度需要多少空间呢?

    4 回复  |  直到 7 年前
        1
  •  54
  •   dsimcha    15 年前

    在Java中, null 只是一个引用(基本上是一个受限制的指针)可以拥有的值。这意味着引用什么都没有。在这种情况下,您仍然需要消耗空间作为参考。这是32位系统上的4个字节或64位系统上的8个字节。但是,在实际分配该类的实例以指向引用之前,您不会为引用指向的类占用任何空间。

    编辑:对于字符串,a String 在Java中,每个字符需要16位(2字节),再加上少量的簿记开销,这可能是未记录的和实现特定的。

        2
  •  11
  •   Jacky    12 年前

    我想补充一下:

    1. 引用类型的变量将初始化为空值。
    2. 空不是对象。因为(空的instanceof对象)等于false
    3. JVM中只有一个空值。不管有多少变量引用空值。

      对象s=(字符串)空;

      对象i=(integer)为空;

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

        3
  •  4
  •   eckes    10 年前

    你可以用 jol 以获取该类的布局。(不过要小心,您可能需要对其背后的机制有更深入的了解,不要盲目相信结果,并且要意识到它只是对当前使用的虚拟机的估计(在我的情况下是1.7.0 x64 win:)。

    我使用的是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
    

    这些只是对象本身的布局如果字段为空,那么它将不会指向更多的对象,否则您必须查看目标类型( URL String )还有。(如果您有所有实例的多个实例,则取决于您是多次使用相同的实例还是使用不同的实例)。在内存中不能跳过空字段,因为它需要在分配实例时调整其大小。所以这些字段都是预先构建的,它们只是不引用堆中其他地方分配的对象。

    注意:如果实现一个默认的构造函数,您会得到更多的细节,但是在这个特定情况下,大小调整是相同的。如果您想知道字段的序列和填充来自何处,可以检查 this article -(基本上,它将8个字节上的对象对齐,按大小对字段排序,将同一类型分组在一起,最后引用。超级类型的字段是第一个,4字节对齐。)

        4
  •  0
  •   Sidharth Singh    7 年前

    空表示0。通常在内存中定义了一个空位置。每当有人用编程语言指向它。一切都指向同一个地方。这意味着只有一个4字节的内存为空。那么,无论指向它的是什么,都不会消耗更多的内存。NULL的定义是特定于语言的,但定义它是空的*PTR=0;在C和C++中是常见的。Java必须类似地定义它。不可能指向任何OFC。你必须指出一些事情。但是我们定义了一个普通的“无”字,所有指向它的东西只消耗了那个空间。