Javaオブジェクトのメモリ使用量を計測してみました。
計測を行ったJDKはWindowsの1.4.2_04です。
基本的に、Javaではプリミティブ型以外の全オブジェクトを生成するときに
new演算子を使用します。
つまり、メモリ確保が行われるタイミングはnew演算子が実行される時に限られます。
フィールドが一つも無いオブジェクトを生成すると、8byteのメモリを消費します。
Object obj = new Object();
フィールドが一つ以上あるオブジェクトを生成すると、8+α
byteのメモリを消費します。α
の値は、このクラスが保持するフィールドに依存します。
フィールドの型により、消費するbyte数が異なります。
1byteを消費します。
2byteを消費します。
4byteを消費します。
8byteを消費します。
4byteを消費します。
全フィールドの消費byte合計値が α
になります。
ただし、α
の値は8単位で切り上げられます。
例えば、byteのフィールドを一つだけ持つクラスの消費メモリは16byteになります。
クラスが保持するメソッドやstaticフィールドは、消費メモリに関係しません。
また、このクラスがスーパークラスを持つ場合には
そのスーパークラスが保持するフィールドも足し合わせた合計値が消費メモリになります。
java標準クラスでいくつか例を挙げます。
8byteです。
24byteです。
312byteです。
配列を確保するときには、β = 配列のサイズ×α + 12
byteのメモリを消費します。α
の値は、前項で示した計算式に従います。
ただし値の切り上げは行われません。
その代わり、β
の値が8単位で切り上げられます。
例を挙げます。
Calendar[] cals = new Calendar[1000];
この場合、消費されるメモリ量は 1000 * 4 + 12 = 4012 -> 4016 になります。
short[] values = new short[1000];
この場合、消費されるメモリ量は 1000 * 2 + 12 = 2012 -> 2016 になります。
プリミティブ型以外の配列に値を代入する場合は、
その都度オブジェクトを生成する必要があるので
別途メモリが消費されることになります。
例を挙げます。
Calendar[] cals = new Calendar[1000]; for (int i = 0 ; i < cals.length ; i++) { cals[i] = Calendar.getInstance(); }
まず、先程示したように配列の生成に4096byteが消費されます。
さらに、これらの配列の格納するCalendarクラスのインスタンスの生成に
312 * 1000 = 312000byteが消費されることになります。