2010-03-12 86 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个字节的对象对齐,按大小对字段进行排序,将相同类型组合在一起,引用最后一个字段。字节对齐。)