先日、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にしていますが、要素数が増えれば当然結果は色々と変わってくると思います