minimize

事業拡大のため、新しい仲間を募集しています。
→詳しくはこちら

Javaオブジェクトのメモリ使用量を計測してみました。
計測を行ったJDKはWindowsの1.4.2_04です。

基本的に、Javaではプリミティブ型以外の全オブジェクトを生成するときに
new演算子を使用します。
つまり、メモリ確保が行われるタイミングはnew演算子が実行される時に限られます。

全てのオブジェクト

フイールド数0

フィールドが一つも無いオブジェクトを生成すると、8byteのメモリを消費します。

Object obj = new Object();

フイールド数1以上

フィールドが一つ以上あるオブジェクトを生成すると、8+α byteのメモリを消費します。
α の値は、このクラスが保持するフィールドに依存します。

フィールドの型により、消費するbyte数が異なります。

byte / boolean

1byteを消費します。

short

2byteを消費します。

int / float

4byteを消費します。

long / double

8byteを消費します。

全てのオブジェクトまたは配列

4byteを消費します。

全フィールドの消費byte合計値が α になります。
ただし、α の値は8単位で切り上げられます。
例えば、byteのフィールドを一つだけ持つクラスの消費メモリは16byteになります。

クラスが保持するメソッドやstaticフィールドは、消費メモリに関係しません。
また、このクラスがスーパークラスを持つ場合には
そのスーパークラスが保持するフィールドも足し合わせた合計値が消費メモリになります。

java標準クラスでいくつか例を挙げます。

java.lang.Integer

8byteです。

java.util.Date

24byteです。

java.util.Calendar

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が消費されることになります。