1

重複の可能性:
Java で、オブジェクトのサイズを決定する最良の方法は何ですか?

ネットでこのコードを見つけました:

static Runtime runtime = Runtime.getRuntime();
...
long start, end;
Object obj;
runtime.gc();
start = runtime.freememory();
obj = new Object(); // Or whatever you want to look at
end =  runtime.freememory();
System.out.println("That took " + (start-end) + " 
bytes.");

しかし、それはあまり信頼性が高くありません。より良い方法について何か考えはありますか?

4

2 に答える 2

2

JVM は、複数のスレッドで同時に実行できるように、メモリをチャンクで割り当てます。これはThread-Local Allocation Bufferと呼ばれます。

TLAB - スレッド ローカル割り当てバッファー。同期せずにヒープ領域をすばやく割り当てるために使用されます。コンパイルされたコードには、現在のスレッドの TLAB の最高水位標をバンプしようとするいくつかの命令の「高速パス」があり、バンプされたマークが TLAB 固有の制限アドレスよりも前にある場合、オブジェクトを正常に割り当てます。

でこれをオフに-XX:-UseTLABすると、より正確なメモリ使用量の情報が得られます。

public static void main(String... args) {
    for (int i = 0; i < 10; i++) {
        long used1 = memoryUsed();
        new Object();
        long used2 = memoryUsed();
        System.out.println(used2 - used1);
    }
}

public static long memoryUsed() {
    return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}

デフォルトのオプションで印刷

0 0 0 0 0 0 0 0 0

-XX:-UseTLAB

16 16 16 16 16 16 16 16 16 16

于 2012-12-01T12:41:10.953 に答える
1

オブジェクトのサイズを測定した経験が少しありますが、私が学んだことの 1 つは、プロファイラーを信用しないことです。実際の測定値は提供しませんが、推測します。これを非常に具体的にするために、64 ビット VM で参照配列のサイズを 100% 誤って判断しました。実際のサイズはスロットあたり 32 ビットですが、64 ビットと推測しました。

測定方法は、特定の構成で十分に注意を払い、一貫した結果が得られることを確認する限り、実際には問題ありません。追加のアドバイス:

  1. 1 つのオブジェクトのサイズを測定するのではなく、1000 または 100 万のオブジェクトの配列のサイズを測定します。これは、オブジェクト間でデータを共有する場合に、より現実的な結果を得るために重要です (非常に典型的なシナリオ)。配列のサイズを変更して、オブジェクトごとの結果が常に同じであることを確認します。

  2. System.gc()配列を割り当てる前後に2 ~ 3 回実行し、それらの間で 0.5 秒ほど一時停止します。

  3. freeMemoryヒープが大きくなる可能性があるため、測定するだけではありません。測定してtotalMemory() - freeMemory()ください。

于 2012-12-01T12:42:18.317 に答える