简体   繁体   English

试图了解JOLSample_16_AL_LL中ArrayList的占用空间

[英]Trying to understand the footprint of ArrayList in JOLSample_16_AL_LL

Here is a link to the code in question - http://hg.openjdk.java.net/code-tools/jol/file/07087260ce41/jol-samples/src/main/java/org/openjdk/jol/samples/JOLSample_16_AL_LL.java 这是有关代码的链接-http://hg.openjdk.java.net/code-tools/jol/file/07087260ce41/jol-samples/src/main/java/org/openjdk/jol/samples/ JOLSample_16_AL_LL.java

public static void main(String[] args) throws Exception {
    out.println(VM.current().details());

    List<Integer> al = new ArrayList<Integer>();
    List<Integer> ll = new LinkedList<Integer>();

    for (int i = 0; i < 1000; i++) {
        Integer io = i; // box once
        al.add(io);
        ll.add(io);
    }

    PrintWriter pw = new PrintWriter(out);
    pw.println(GraphLayout.parseInstance(al).toFootprint());
    pw.println(GraphLayout.parseInstance(ll).toFootprint());
    pw.println(GraphLayout.parseInstance(al, ll).toFootprint());
    pw.close();
}

When I run the code as is I see the following: 当我按原样运行代码时,我看到以下内容:

java.util.ArrayList@5f205aad footprint:
     COUNT       AVG       SUM   DESCRIPTION
         1      4952      4952   [Ljava.lang.Object;
      1000        16     16000   java.lang.Integer
         1        24        24   java.util.ArrayList
      1002               20976   (total)

I am unsure where the 4952 bytes for [Ljava.lang.Object; 我不确定[Ljava.lang.Object;的4952字节在哪里; is coming from. 来自。 If I update the ArrayList creation and set a initial size to 1000 so that there is no growing I get the following: 如果我更新ArrayList的创建并将初始大小设置为1000,以便不增长,则会得到以下信息:

java.util.ArrayList@5f205aad footprint:
 COUNT       AVG       SUM   DESCRIPTION
     1      4016      4016   [Ljava.lang.Object;
  1000        16     16000   java.lang.Integer
     1        24        24   java.util.ArrayList
  1002               20040   (total)

Thanks. 谢谢。

UPDATE 更新

I turned off CompressedOops (-XX:-UseCompressedOops). 我关闭了CompressedOops(-XX:-UseCompressedOops)。 Here is the new result: 这是新结果:

java.util.ArrayList@1996cd68d footprint:
 COUNT       AVG       SUM   DESCRIPTION
     1      8024      8024   [Ljava.lang.Object;
  1000        24     24000   java.lang.Integer
     1        40        40   java.util.ArrayList
  1002               32064   (total)

So when disabling CompressedOops the reference sizes increase to 8 bytes. 因此,当禁用CompressedOops时,参考大小将增加到8个字节。 To me that makes even more sense that the Object array holds the references to the 1000 Integer Objects. 对我来说,更有意义的是Object数组包含对1000个Integer Objects的引用。

ArrayList internally is backed by an Object[] as a buffer, which grows as needed . ArrayList内部由Object[]作为缓冲区支持,并根据需要增长

An array of objects is actually an array of object references. 对象数组实际上是对象引用数组。 In your case, it looks like each object reference is 4 bytes , so an array of them would use 4 * length bytes, plus some overhead such as the length of the array and other stuff . 在您的情况下,看起来每个对象引用都是4个字节 ,因此它们的数组将使用4 * length字节,外加一些开销,例如数组的长度和其他内容

When you allow the ArrayList to grow naturally, any unused indexes in the buffer array default to null , which still uses 4 bytes of memory per index. 当您允许ArrayList自然增长时,缓冲区数组中所有未使用的索引默认为null ,每个索引仍使用4个字节的内存。

The ArrayList that allows growth has probably expanded to (4952 - 16) / 4 = ~1234 capacity . 允许增长的ArrayList可能已扩展为(4952-16-1)/ 4 = 〜1234容量

While the ArrayList that doesn't require growth only has 1000 capacity . 不需要增长的ArrayList只有1000个容量

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM