3

Java で特定のオブジェクト タイプのサイズを把握しようとしています。私の具体的な質問は、64 ビット マシン上の以下のオブジェクト/プリミティブのサイズです。主に BigDecimal に関心がありますが、他のものも知っておくとよいでしょう。

  1. float (プリミティブ)
  2. double (プリミティブ)
  3. ブール値 (プリミティブ)
  4. フロート (オブジェクト)
  5. Double (オブジェクト)
  6. BigDecimal (オブジェクト)
  7. ブール (オブジェクト)
  8. オブジェクト ポインタ

私の研究:

SizeOf ライブラリ ( http://sizeof.sourceforge.net/ )を使用して、さまざまなオブジェクト サイズについて実験的にいくつかのテストを行いましたが、BigDecimal、Double、Float、Boolean の結果に少し戸惑っています。1 つのオブジェクトのサイズが 12,000 バイトを超えていると報告されていますが、これは事実ではないようです。本当に 12k バイトであるか、SizeOf ライブラリが正しく機能していません。jvisualvm を使用してこれを確認し、後で投稿します。

BigDecimal の別のスレッドで別の投稿を見つけましたが、答えが正しいかどうかはわかりません: Java BigDecimal メモリ使用量?

所見:

  1. sizeof.jar が出力する数値はバイト単位です。
  2. BigDecimal/Double/Float が大量のメモリを消費するか、ライブラリのサイズに問題があります。
  3. Sizeof は、プリミティブ型にとって意味のある数値を報告しているようです
  4. 64 ビット マシンのオブジェクト ポインタは 8 バイトです
  5. TestEmpty は何も入っていないクラスです。参考までに作成しました。ちょうど 8 バイトであるはずなのに、なぜ 16 バイトと報告されているのかわかりません。
  6. プリミティブ サイズ (TestDouble/TestFloat/etc) を測定するために追加したテスト クラスでは、SizeOf が実際にはオブジェクト ポインター (TestFloat) とプリミティブのサイズを報告しているため、報告された数から 8 バイトを削除する必要があります。

ブール値:

ブール値は興味深いものであり、さらに分析する価値があるようです。それらはまとめてパックする必要があり、実際にはそれぞれ 1 バイトかかるようです。Javaが64ビットシステムでメモリを予約すると、8バイト以上しか割り当てられないと推測しています。ブール値は実際には 1 ビットだけを格納する必要があるため、1 つのブール値に 8 バイトを割り当てるのは無駄です。したがって、これを補うために、Java は 8 ブール値を 8 バイトの連続メモリにパックすると推測しています。私が追加する8つのブール値ごとに、メモリが8バイト増加するようです。8 バイトに 64 ビットを格納する方がスペース効率が高くなりますが、これらのブール値の処理は、アンパックしてプロセッサ レジスタに送信する必要があるため、遅くなると思います。

テストの実施方法:

  1. http://sizeof.sourceforge.net/から sizeof jar を取得します。
  2. プロジェクト/クラスパスに sizeof.jar を追加します
  3. sizeof の javaagent をサーバーの起動に追加します。
  4. sizeof はオブジェクトに対してのみ機能するため、bool/float/double のサイズをテストするために、単一のプリミティブ変数 (TestBool、TestDoubld、TestFloat など) だけを含むクラスを作成しました。
  5. ブール値のサイズを確認するために、いくつかのテスト クラスを作成しました。たとえば、TestPacked10Bool には 10 個のブール値があります。
  6. 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

4

0 に答える 0