覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

size=1のListのメモリサイズってどの程度

先日、Arrays#asListで生成されるArrayListについてのエントリを書きました。

そのエントリ書いた後に、ふとメモリサイズの違いもあるかなと思ってJOLで測定してみました。


対象

生成するList

今回は条件を単純化して、生成するListを以下内容にしています。

  • 生成するのは文字列List
  • 要素数は1
  • 要素の内容は "hello" という文字列

Listの生成方法

以下操作によって生成された各Listを今回の測定対象としています

  • java.util.Arrays#asList
  • java.util.ArrayList のデフォルトコンストラクタ + addで要素追加
  • java.util.ArrayList の キャパシティを指定するコンストラクタ(引数に1を指定) + addで要素追加
  • java.util.LinkedList のデフォルトコンストラクタ + addで要素追加
  • java.util.concurrent.CopyOnWriteArrayList のデフォルトコンストラクタ + addで要素追加
  • java.util.Collections#singletonList


メモリサイズ取得

以下のサンプルコードを実行してメモリサイズを取得してみました

■サンプルコード

import org.openjdk.jol.info.GraphLayout;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;


public class ListSample {

    public static void main(String[] args) {
        List<String> list1 = Arrays.asList("hello");
        String className1 = list1.getClass().getName();
        System.out.println("## Arrays#asList");

        System.out.println(className1 + " totalSize(byte) -> " + GraphLayout.parseInstance(list1).totalSize());
        System.out.println(className1 + " footprint -> \n" + GraphLayout.parseInstance(list1).toFootprint());

        System.out.println("--------------------");


        List<String> list2 = new ArrayList<>();
        list2.add("hello");

        String className2 = list2.getClass().getName();
        System.out.println("## new ArrayList()");

        System.out.println(className2 + " totalSize(byte) -> " + GraphLayout.parseInstance(list2).totalSize());
        System.out.println(className2 + " footprint -> \n" + GraphLayout.parseInstance(list2).toFootprint());

        System.out.println("--------------------");


        List<String> list3 = new ArrayList<>(1);
        list3.add("hello");

        String className3 = list3.getClass().getName();
        System.out.println("## new ArrayList(initialCapacity=1)");

        System.out.println(className3 + " totalSize(byte) -> " + GraphLayout.parseInstance(list3).totalSize());
        System.out.println(className3 + " footprint -> \n" + GraphLayout.parseInstance(list3).toFootprint());

        System.out.println("--------------------");

        List<String> list4 = new LinkedList<>();
        list4.add("hello");

        String className4 = list4.getClass().getName();
        System.out.println("## new LinkedList");

        System.out.println(className4 + " totalSize(byte) -> " + GraphLayout.parseInstance(list4).totalSize());
        System.out.println(className4 + " footprint -> \n" + GraphLayout.parseInstance(list4).toFootprint());

        System.out.println("--------------------");

        List<String> list5 = new CopyOnWriteArrayList<>();
        list5.add("hello");

        String className5 = list5.getClass().getName();
        System.out.println("## new CopyOnWriteArrayList");

        System.out.println(className5 + " totalSize(byte) -> " + GraphLayout.parseInstance(list5).totalSize());
        System.out.println(className5 + " footprint -> \n" + GraphLayout.parseInstance(list5).toFootprint());

        System.out.println("--------------------");

        List<String> list6 = Collections.singletonList("hello");

        String className6 = list6.getClass().getName();
        System.out.println("## Collections.singletonList");

        System.out.println(className6 + " totalSize(byte) -> " + GraphLayout.parseInstance(list6).totalSize());
        System.out.println(className6 + " footprint -> \n" + GraphLayout.parseInstance(list6).toFootprint());
    }
}


■実行結果

## Arrays#asList
java.util.Arrays$ArrayList totalSize(byte) -> 104
java.util.Arrays$ArrayList footprint -> 
java.util.Arrays$ArrayList@36baf30cd footprint:
     COUNT       AVG       SUM   DESCRIPTION
         1        32        32   [C
         1        24        24   [Ljava.lang.String;
         1        24        24   java.lang.String
         1        24        24   java.util.Arrays$ArrayList
         4                 104   (total)


--------------------
## new ArrayList()
java.util.ArrayList totalSize(byte) -> 136
java.util.ArrayList footprint -> 
java.util.ArrayList@1edf1c96d footprint:
     COUNT       AVG       SUM   DESCRIPTION
         1        32        32   [C
         1        56        56   [Ljava.lang.Object;
         1        24        24   java.lang.String
         1        24        24   java.util.ArrayList
         4                 136   (total)


--------------------
## new ArrayList(initialCapacity=1)
java.util.ArrayList totalSize(byte) -> 104
java.util.ArrayList footprint -> 
java.util.ArrayList@1963006ad footprint:
     COUNT       AVG       SUM   DESCRIPTION
         1        32        32   [C
         1        24        24   [Ljava.lang.Object;
         1        24        24   java.lang.String
         1        24        24   java.util.ArrayList
         4                 104   (total)


--------------------
## new LinkedList
java.util.LinkedList totalSize(byte) -> 112
java.util.LinkedList footprint -> 
java.util.LinkedList@41975e01d footprint:
     COUNT       AVG       SUM   DESCRIPTION
         1        32        32   [C
         1        24        24   java.lang.String
         1        32        32   java.util.LinkedList
         1        24        24   java.util.LinkedList$Node
         4                 112   (total)


--------------------
## new CopyOnWriteArrayList
java.util.concurrent.CopyOnWriteArrayList totalSize(byte) -> 152
java.util.concurrent.CopyOnWriteArrayList footprint -> 
java.util.concurrent.CopyOnWriteArrayList@6f2b958ed footprint:
     COUNT       AVG       SUM   DESCRIPTION
         1        32        32   [C
         1        24        24   [Ljava.lang.Object;
         1        24        24   java.lang.String
         1        24        24   java.util.concurrent.CopyOnWriteArrayList
         1        16        16   java.util.concurrent.locks.ReentrantLock
         1        32        32   java.util.concurrent.locks.ReentrantLock$NonfairSync
         6                 152   (total)


--------------------
## Collections.singletonList
java.util.Collections$SingletonList totalSize(byte) -> 80
java.util.Collections$SingletonList footprint -> 
java.util.Collections$SingletonList@cac736fd footprint:
     COUNT       AVG       SUM   DESCRIPTION
         1        32        32   [C
         1        24        24   java.lang.String
         1        24        24   java.util.Collections$SingletonList
         3                  80   (total)


結果

表にまとめると以下の通りです

Listの生成方法 メモリサイズ(byte)
Arrays#asList 104
ArrayList のデフォルトコンストラクタ + addで要素追加 136
ArrayList の キャパシティを指定するコンストラクタ + addで要素追加 104
LinkedList のデフォルトコンストラクタ + addで要素追加 112
CopyOnWriteArrayList のデフォルトコンストラクタ + addで要素追加 152
Collections#singletonList 80


今回は要素数=1にしていますが、要素数が増えれば当然結果は色々と変わってくると思います



関連エントリ