Java で特定のオブジェクト タイプのサイズを把握しようとしています。私の具体的な質問は、64 ビット マシン上の以下のオブジェクト/プリミティブのサイズです。主に BigDecimal に関心がありますが、他のものも知っておくとよいでしょう。
- float (プリミティブ)
- double (プリミティブ)
- ブール値 (プリミティブ)
- フロート (オブジェクト)
- Double (オブジェクト)
- BigDecimal (オブジェクト)
- ブール (オブジェクト)
- オブジェクト ポインタ
私の研究:
SizeOf ライブラリ ( http://sizeof.sourceforge.net/ )を使用して、さまざまなオブジェクト サイズについて実験的にいくつかのテストを行いましたが、BigDecimal、Double、Float、Boolean の結果に少し戸惑っています。1 つのオブジェクトのサイズが 12,000 バイトを超えていると報告されていますが、これは事実ではないようです。本当に 12k バイトであるか、SizeOf ライブラリが正しく機能していません。jvisualvm を使用してこれを確認し、後で投稿します。
BigDecimal の別のスレッドで別の投稿を見つけましたが、答えが正しいかどうかはわかりません: Java BigDecimal メモリ使用量?
所見:
- sizeof.jar が出力する数値はバイト単位です。
- BigDecimal/Double/Float が大量のメモリを消費するか、ライブラリのサイズに問題があります。
- Sizeof は、プリミティブ型にとって意味のある数値を報告しているようです
- 64 ビット マシンのオブジェクト ポインタは 8 バイトです
- TestEmpty は何も入っていないクラスです。参考までに作成しました。ちょうど 8 バイトであるはずなのに、なぜ 16 バイトと報告されているのかわかりません。
- プリミティブ サイズ (TestDouble/TestFloat/etc) を測定するために追加したテスト クラスでは、SizeOf が実際にはオブジェクト ポインター (TestFloat) とプリミティブのサイズを報告しているため、報告された数から 8 バイトを削除する必要があります。
ブール値:
ブール値は興味深いものであり、さらに分析する価値があるようです。それらはまとめてパックする必要があり、実際にはそれぞれ 1 バイトかかるようです。Javaが64ビットシステムでメモリを予約すると、8バイト以上しか割り当てられないと推測しています。ブール値は実際には 1 ビットだけを格納する必要があるため、1 つのブール値に 8 バイトを割り当てるのは無駄です。したがって、これを補うために、Java は 8 ブール値を 8 バイトの連続メモリにパックすると推測しています。私が追加する8つのブール値ごとに、メモリが8バイト増加するようです。8 バイトに 64 ビットを格納する方がスペース効率が高くなりますが、これらのブール値の処理は、アンパックしてプロセッサ レジスタに送信する必要があるため、遅くなると思います。
テストの実施方法:
- http://sizeof.sourceforge.net/から sizeof jar を取得します。
- プロジェクト/クラスパスに sizeof.jar を追加します
- sizeof の javaagent をサーバーの起動に追加します。
- sizeof はオブジェクトに対してのみ機能するため、bool/float/double のサイズをテストするために、単一のプリミティブ変数 (TestBool、TestDoubld、TestFloat など) だけを含むクラスを作成しました。
- ブール値のサイズを確認するために、いくつかのテスト クラスを作成しました。たとえば、TestPacked10Bool には 10 個のブール値があります。
- 64ビットシステムで実行されました。
私のテストのコードは次のとおりです。
public static void testObjectSizes()
{
List <Object> items = new ArrayList<Object>();
items.add(new BigDecimal(0));
items.add(new BigDecimal(1000000000));
items.add(new BigDecimal("1000000000"));
items.add(new BigDecimal("1000000000000000000000"));
items.add(new BigDecimal("1000000000.0000000001"));
items.add(new BigDecimal("1000000000000000000000.0000000001"));
items.add(new BigDecimal("1000000000000000000000.0000000000000000000001"));
items.add(new TestBigDecimal());
items.add(new Double(0));
items.add(new Double(1000000000));
items.add(new Float(0));
items.add(new Float(1000000000));
items.add(new TestDouble());
items.add(new TestEmpty());
items.add(new TestFloat());
items.add(new Boolean(true));
items.add(new TestBool());
items.add(new TestPacked2Bool());
items.add(new TestPacked3Bool());
items.add(new TestPacked4Bool());
items.add(new TestPacked5Bool());
items.add(new TestPacked6Bool());
items.add(new TestPacked7Bool());
items.add(new TestPacked8Bool());
items.add(new TestPacked9Bool());
items.add(new TestPacked10Bool());
items.add(new TestPacked11Bool());
items.add(new TestPacked12Bool());
items.add(new TestPacked13Bool());
items.add(new TestPacked14Bool());
items.add(new TestPacked15Bool());
items.add(new TestPacked16Bool());
items.add(new TestPacked17Bool());
items.add(new TestPacked64Bool());
for (int i = 0 ;i < items.size(); i++)
{
System.out.println("test " + i + " - " +items.get(i).getClass().getName() + " size:" + SizeOf.deepSizeOf(items.get(i)));
}
}
出力:
テスト 0 - java.math.BigDecimal サイズ:12144
テスト 1 - java.math.BigDecimal サイズ:12144
テスト 2 - java.math.BigDecimal サイズ:12144
テスト 3 - java.math.BigDecimal サイズ:12216
テスト 4 - java.math.BigDecimal サイズ:12208
テスト 5 - java.math.BigDecimal サイズ:12216
テスト 6 - java.math.BigDecimal サイズ:12224
テスト 7 - com.george.test.info.TestBigDecimal サイズ:12160
テスト 8 - java.lang.Double サイズ:296
テスト 9 - java.lang.Double サイズ:296
テスト 10 - java.lang.Float サイズ:288
テスト 11 - java.lang.Float サイズ:288
テスト 12 - com.george.test.info.TestDouble サイズ: 24
テスト 13 - com.george.test.info.TestEmpty サイズ: 16
テスト 14 - com.george.test.info.TestFloat サイズ:16
テスト 15 - java.lang.Boolean サイズ:320
テスト 16 - com.george.test.info.TestBool サイズ:16
テスト 17 - com.george.test.info.TestPacked2Bool サイズ:16
テスト 18 - com.george.test.info.TestPacked3Bool サイズ:16
テスト 19 - com.george.test.info.TestPacked4Bool サイズ:16
テスト 20 - com.george.test.info.TestPacked5Bool サイズ: 24
テスト 21 - com.george.test.info.TestPacked6Bool サイズ: 24
テスト 22 - com.george.test.info.TestPacked7Bool サイズ: 24
テスト 23 - com.george.test.info.TestPacked8Bool サイズ: 24
テスト 24 - com.george.test.info.TestPacked9Bool サイズ: 24
テスト 25 - com.george.test.info.TestPacked10Bool サイズ: 24
テスト 26 - com.george.test.info.TestPacked11Bool サイズ: 24
テスト 27 - com.george.test.info.TestPacked12Bool サイズ: 24
テスト 28 - com.george.test.info.TestPacked13Bool サイズ:32
テスト 29 - com.george.test.info.TestPacked14Bool サイズ:32
テスト 30 - com.george.test.info.TestPacked15Bool サイズ:32
テスト 31 - com.george.test.info.TestPacked16Bool サイズ:32
テスト 32 - com.george.test.info.TestPacked17Bool サイズ:32
テスト 33 - com.george.test.info.TestPacked64Bool サイズ:80