2009-04-25 5 views
17

長命のオブジェクトがたくさんある(何百万もの)アプリケーションのヒープサイズの使用を最適化するにはどうすればよいですか? (ビッグキャッシュ、DBからレコードをたくさんロード)Javaアプリケーションのメモリを効率的にするにはどうすればよいですか?

  • 避け重複したオブジェクトに を他のデータ型を表すためにjava.lang.Stringで
    • 避けて右のデータ型を使用します
      • 値が事前にわかっている場合はenumを使用する
      • オブジェクトプールを使用する
      • String.intern()(良いアイデア?)
    • ロード/ Iは、一般的なプログラミングやJava、特定の答えを探していますあなたは

    を必要とするオブジェクトのみを保持します。ファンキーなコンパイラスイッチはありません。

    編集:

    は、ヒープ内の数百万回を表示することができPOJOのメモリ表現を最適化します。

    ユースケース(のPOJOに変換)

    • ロードメモリ内の巨大なcsvファイル
    • 利用答えのデータベース

    再開からレコードの百万を取得するために休止状態:

    • フライウェイトパターンを使用
    • コピーライト
    • 3つのプロパティを持つ10Mオブジェクトを読み込む代わりに、サイズ10Mの3つの配列(または他のデータ構造)を持つ方が効率的ですか?それは、詳細な提供には少し難しいよう
  • +9

    ... :) –

    +2

    私はアセンブラが役立つだろうことを疑う - 開発時間が大幅に長くなり、クロスプラットフォームではないでしょう。 ;) – Fortyrunner

    +3

    @Fortyrunner私はDesmondが冗談を言っていたと思う。 –

    答えて

    17

    (あなたがメモリ上本当に不足している場合...データを操作するための痛みをすることなく、でした)あなたは、あなたが保存するために探しているオブジェクトの種類を言っていません助言。しかし、いくつかの(排他的ではない)のアプローチは、順不同で、以下のとおりです。

    • は、可能な限りflyweight pattern を使用してください。
    • ディスクにキャッシュする。 Javaのキャッシュソリューションは numerousです。
    • String.internをお勧めしますか?質問は hereをご覧ください。 String.intern()、その適性については の議論があります。
    • softまたはweak の参照を使用して、必要に応じて を再作成/再ロードできるデータを保存します。キャッシング技術で ソフトを使用する方法については、 hereを参照してください。

    保存しているオブジェクトの内部と寿命について知ると、より詳細な回答が得られます。

    +0

    なぜDownvotedですか? –

    20

    メモリプロファイラを使用し、メモリが消費されている場所を参照して最適化することをお勧めします。量的な情報がなければ、効果がないか、事態を悪化させることになります。

    オブジェクトのサイズが小さい場合は、データの表現を変更することができます。 たとえば、行ごとに1つのオブジェクトではなく、各列のオブジェクト配列を持つ一連の列としてデータ表を表すことができます。これにより、個々の行を表す必要がない場合は、各オブジェクトのオーバーヘッドが大幅に削減されます。例えば12列と10,000,000行の表は、1千万ではなく1列に1つの12個のオブジェクトを使用できます。

    +0

    オブジェクトの数を最小限に抑えるための優れたトリックです。 – Boune

    +1

    メモリプロファイラーは、どのクラスインスタンスがすべてのメモリを占有しているのかわからない人にとって、良い出発点であることに同意します。問題はもっと先です。もし私があらかじめ10M pojo#1を記憶しているとすれば、各インスタンスの消費量をどのように最小限に抑えるのでしょうか? – Boune

    11

    オブジェクトモデルの正常化を確認し、値を重複しないでください。

    エヘン、そして、それはオブジェクトの唯一の何百万人だ場合、私は、私はちょうどまともな64ビットVMとラムの多くのために行くと思う;)

    +1

    これはおそらく最も費用対効果の高いソリューションです:-) –

    +0

    +1 - それは問題の中心に切れています。 – duffymo

    +0

    偉大な答え。データのキャッシュを使用し、重複するレコードとフィールドを減らすことは、大きな節約になります。 – Fortyrunner

    1

    私はピーターがalredy作っポイントに何かを追加したいに(することができます彼の答えにコメントしないでください:()それは常に私たちが無視したルーチンの時間intution.80%で行くよりメモリプロファイラー(チェックjava memory profiler)を使用する方が良いですit.alsoコレクションクラスは、メモリすべてのあなたの「ライブ」オブジェクトの概要を必要とするのでリーク。

    4

    通常「プロファイラ」には、多くのあなたを助けにはなりません。あなたは、ヒープ・ダンプ・アナライザを必要としています。私はEclipse Memory analyzerをお勧めします。

    文字列で始まる、重複したオブジェクトを確認します。 フライトウェイト、コピーオンリー、遅延初期化(Googleがあなたの友人になる)などのパターンを適用できるかどうかを確認します。

    2

    メモリに格納するオブジェクトの数を減らすことができます。 :)ディスクに流出するキャッシュを使用するか、テラコッタを使用してヒープ(仮想)をクラスタ化して、未使用のパーツをメモリからフラッシュして透過的にフォールトバックさせます。

    0

    ファンシーなもの: 。現在のワーキングセットのみを展開します。あなたのデータがうまく機能する良い地域を持っているなら。

    より良いデータ構造を使用してください。 javaの標準的なコレクションはかなりメモリを消費します。

    [何よりよいデータ構造がある]

    • あなたがコレクションのソースを見てみるならば、あなたはあなたがコレクションにアクセスする方法で自分を制限する場合は、あなたがスペースを節約できることがわかります要素ごとに。
    • コレクションの処理方法は大規模なコレクションには適していません。コピーが多すぎます。大規模なコレクションの場合、btreeのようなブロックベースのアルゴリズムが必要です。
    +0

    より良いデータ構造をどのように定義しますか?あなたはそれをどのように実装しますか? – Boune

    0

    は精通してVM command line options、ガベージコレクションについて特にチューニングを取得いくつかの時間をお過ごしください。これによりオブジェクトによって使用されるメモリは変更されませんが、多くのRAMを搭載したマシン上のメモリを消費するアプリケーションでは、パフォーマンスに大きな影響を与えます。

    1

    数百万の整数と浮動小数点数などがある場合、アルゴリズムがプリミティブの配列でデータを表現できるかどうかを確認してください。これは、各ガベージコレクションの参照数が減り、CPUコストが削減されることを意味します。 no longerを使用しているすべてのvariables

    0
    1. Assign null値。従ってmake it available for Garbage collection
    2. De-reference the collections使用が終了すると、GCはそれを掃引しません。
    +1

    私は項目1に同意しません。私はgcにそれがすると思われることをさせます。これは、すべての変数ではなく、有用であるケースはほんのわずかです(配列、コレクション)。 http://stackoverflow.com/questions/449409/does-assigning-objects-to-null-in-java-impact-garbage-collection – Boune

    3

    ここからリンクされたこのプレゼンテーションをご覧ください。これは、一般的なJavaオブジェクトとプリミティブのメモリ使用をレイアウトし、余分なメモリがどこにあるのかを理解するのに役立ちます。アセンブリでプログラムを書くことによって

    Building Memory-efficient Java Applications: Practices and Challenges

    関連する問題