2

問題のコードへのリンクは次のとおりです- 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();
}

コードをそのまま実行すると、次のように表示されます。

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)

[Ljava.lang.Object; の 4952 バイトがどこにあるのかわかりません。から来ています。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)

ありがとう。

アップデート

CompressedOops (-XX:-UseCompressedOops) をオフにしました。新しい結果は次のとおりです。

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)

そのため、CompressedOops を無効にすると、参照サイズが 8 バイトに増加します。オブジェクト配列が 1000 個の整数オブジェクトへの参照を保持していることは、私にとってさらに理にかなっています。

4

1 に答える 1

3

ArrayList内部的には、必要に応じて成長するObject[]バッファとしてサポートされています。

オブジェクトの配列は、実際にはオブジェクト参照の配列です。あなたの場合、各オブジェクト参照は4 bytesであるように見えるので、それらの配列は4 * lengthバイトを使用し、さらに配列の長さなどのオーバーヘッドやその他のものを使用します。

ArrayListを自然に拡張できるようにすると、バッファ配列内の未使用のインデックスはデフォルトで になりnull、インデックスごとに 4 バイトのメモリが使用されます。

ArrayList成長を可能にするは、おそらく (4952 - 16) / 4 = ~1234 容量に拡張されました。

成長をArrayList必要としない には1000 の容量しかありません。

于 2016-09-12T03:20:26.343 に答える