Java 仕様はメモリの使用を義務付けていないため、これは使用する JVM 実装によって異なります。
確かに、すべての JVM 実装でオブジェクトごとのオーバーヘッドが発生します (たとえば、実行時の型チェックを実装するため)。JVM は、フィールドをメモリ アラインすることを選択する場合があります (一部のプラットフォームでは、これにより、フィールドへのアクセスが大幅に高速化されます)。
ただし、メモリの配置のためにパディングされた配列メンバーがあり、(少なくとも Windows の oracle vm では) boolean[] が要素ごとに 1 バイトかかることを確認できる場合、私は非常に驚くでしょう。
また、適切に大きなヒープをアドレス指定する場合、参照型のフィールドのサイズが 8 バイトになる可能性があることに注意してください。
結論: 本当に知りたい場合は、ターゲット JVM のメモリ消費量を測定してください。
編集:好奇心から、小さな(不正確な)ベンチマークを書きました:
class FourBytes {
byte a,b,c,d;
}
public class Test {
long usedBefore = used();
long used() {
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}
public void before() {
System.gc();
usedBefore = used();
}
public void after(String text) {
long usedAfter = used();
System.out.println(text + "\t" + new BigDecimal(usedAfter - usedBefore).movePointLeft(6) + " bytes");
before();
}
{
int max = 1000000;
before();
boolean[] bools = new boolean[max];
after("boolean in array");
char[] chars = new char[max];
after("char in array ");
Object[] objects = new Object[max];
after("reference type in array");
for (int i = 0; i < max; i++) {
objects[i] = new Object();
}
after("Object instance ");
Byte[] bytes = new Byte[max];
before();
for (int i = 0; i < max; i++) {
bytes[i] = new Byte((byte) i);
}
after("Byte instance ");
Integer[] integers = new Integer[max];
before();
for (int i = 0; i < max; i++) {
integers[i] = new Integer(i);
}
after("Integer instance");
FourBytes[] fbs = new FourBytes[max];
before();
for (int i = 0; i < max; i++) {
fbs[i] = new FourBytes();
}
after("FourBytes instance");
}
public static void main(String[] args) throws Exception {
new Test();
}
}
の上
java version "1.7.0_02"
Java(TM) SE Runtime Environment (build 1.7.0_02-b13)
Java HotSpot(TM) Client VM (build 22.0-b10, mixed mode, sharing)
それは印刷します:
boolean in array 1.183624 bytes
char in array 2.091768 bytes
reference type in array 4.091768 bytes
Object instance 8.023664 bytes
Byte instance 16.133408 bytes
Integer instance 16.147312 bytes
FourBytes instance 16.142568 bytes