4

Java のメモリ オーバーヘッドについてお聞きしたいのですが、大きな ArrayList (61,770 項目) があり、各項目 (オブジェクトとその ArrayList エントリをカウント) が消費するメモリ量を計算しようとしています。すべてのデータがロードされた後、ヒープは ~ 25Mb かかります。ArrayList に項目が 2 つしかない場合、ヒープは ~1Mb かかるので、大まかに:

(24*1024*1024)/61,768 = 407 バイト。

ただし、各オブジェクトのフィールドをカウントすると、148 バイトが得られます (ArrayList を含まず、int=4、float=4、reference=4 と仮定します)。これらの余分なバイトがすべてどこから来たのか知りたいです。から...

ArrayList に格納するオブジェクトはインターフェイスを実装しているため、追加の値を格納していると推測できます。VM は、実装されたメソッドごとに 4 バイトの関数ポインタを格納している可能性があります。彼らが実装するインターフェースには20の機能があるため、さらに80バイト、合計228バイトですが、測定された400バイトにはまだ近くありません。

任意の助けをいただければ幸いです。


うわー、すべての素晴らしい答えをありがとう。

@Bolo: リンクに感謝します。このクラスでは、オブジェクトごとに最大 350 バイトを測定するため、大量のメモリ使用量の原因を確認することはほとんどできません。

@Yuval A: 貴重な情報源であるプレゼンテーションに感謝します。

@ウッコ:指摘された点。

@Jayan: 現在、ヒープをダンプしようとすると、NetBeans プロファイラーでエラーが発生します。後で再試行します。

4

5 に答える 5

6

これらの結果は驚くべきことではありません。JVM は、各オブジェクトに膨大な量のオーバーヘッドを追加します。

JVM メモリのオーバーヘッドにより、1 つのオブジェクトの予想サイズの約 2 倍になることは珍しくありません。

このプレゼンテーションには、Java でのさまざまなデータ構造のメモリ使用量について、素晴らしく詳細な説明と概要が含まれています。

于 2010-04-27T13:18:09.577 に答える
2

ほとんどの場合、ArrayList は要素数よりも大きくなります。getCapacity()基になる配列の現在のサイズを取得するために使用します。

于 2010-04-27T13:14:51.620 に答える
2

あなたのアプローチの大きな問題は、ガベージ コレクターとの相互作用です。それは基本的に、あなたが提案したようなテストを外部から完全に不透明にします。

これをやりたい場合の思考実験として、

  1. JVM を起動し、いくつかのグローバル GC を実行してすべてのジャンクを取り出します
  2. ヒープ サイズと、空き領域の量に関する Java の概念を測定します。
  3. テストを実行する
  4. GCを数回
  5. 手順 2 から測定をやり直します

すべてのことと少しの計算の後、あなたはより近くなりますが、それでも正しくありません. 唯一の本当の解決策は、他の人が言及したように実際に実装を尋ねることです。または、実装の知識からそれを把握します。

于 2010-04-27T13:21:14.590 に答える
1

arraylist によって消費されるメモリは少しあいまいです。

値が完全に割り当てられた後、適切な段階でプロセスのヒープ ダンプを取得します。次に、メモリ アナライザー (Eclipse から) などのツールを使用します。

浅いヒープ サイズと保持ヒープ サイズを見つけます。

于 2010-04-27T13:11:54.040 に答える
0

ちなみに、ArrayListに含まれるオブジェクトの数は正確にわかっているので、array []を使用しないのはなぜですか?そこにあるオブジェクトの数は変わりますか?

于 2010-04-27T14:19:39.007 に答える