質問

Javaのメモリオーバーヘッドについて尋ねたいと思います。私は大きなアレイリスト(61,770アイテム)を持っています(各アイテムが撮影したメモリの量(オブジェクトとその配列エントリをカウント)を計算しようとします。アプリをプロファイリングすることによりすべてのデータがロードされた後、ヒープには〜25MBが必要です。 ArrayListに2つのアイテムしかない場合、ヒープには〜1MBがかかるため、大まかに:

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

でも, 、各オブジェクトのフィールドをカウントすると、148バイト(ArrayListを含めないで、int = 4、float = 4、参照= 4)を取得します。 ...

ArrayListに保存しているオブジェクトがインターフェイスを実装しているため、追加の値を保存し、VMが実装された各メソッドに4byte関数ポインターを保存するのでしょうか?それらが実装するインターフェイスには20の関数があるため、測定された400バイトにまだ近くはありません。

どんな助けも感謝します。


うわー、すべての素晴らしい答えに感謝します。

@Bolo:リンクをありがとう、このクラスIを使用して、オブジェクトごとに約350バイトを測定しているため、大きなメモリ使用量のソースを最も確認できます。

@yuval A:貴重な情報源であるそのプレゼンテーションをありがとう。

@ukko:ポイントが指摘した。

@Jayan:NetBeansプロファイラーは、ヒープを捨てようとするとエラーを与えています。後でもう一度試してみます。

役に立ちましたか?

解決

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

JVMメモリオーバーヘッドのため、単一のオブジェクトの予想サイズの約2倍は珍しくありません。

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

他のヒント

アレイリストは、要素の数よりもほとんど大きいです。使用する getCapacity() 基礎となる配列の現在のサイズを取得します。

あなたのアプローチの大きな問題は、ゴミコレクターとの相互作用です。基本的には、外部から完全に不透明なことを提案したように、あらゆるテストを行います。

これをやりたいなら、思考実験として

  1. JVMを起動し、いくつかのグローバルGCSを実行してすべてのジャンクを取り出します
  2. ヒープのサイズとJavaの概念を測定します。
  3. テストを実行します
  4. GCは数回
  5. ステップ#2から測定値をやり直します

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

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

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

浅く保持されているヒープサイズを見つけます。

サイドノートとして、ArrayListにいくつのオブジェクトがあるかを正確に知っているので、Array []を使用してみませんか?そこにあるオブジェクトの数は変わりますか?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top