7

さて、私はいくつかのオブジェクトの関係を使用してJavaアプリケーションを開発しましたが、これによりメモリ使用量が非常に高くなります。アプリケーションの設計上、オブジェクトを破棄して以前にクリアしたスペースを再利用することが難しいため、Java メモリを管理した経験はありません。たとえば、Observerと MVC パターンを使用しています。

だから、理論はそれを言う..

オブジェクトは、ライブ スレッドまたは静的参照から到達できない場合、ガベージ コレクションまたは GC の対象になります。

つまり、すべての参照が null の場合、オブジェクトはガベージ コレクションの対象になると言えます。

しかし、私の短い経験では、方法がわからない私のようなシナリオがある場合、メモリから削除したいオブジェクトからのすべての参照を破棄するのは難しすぎます (たとえば、フレームが閉じられたとき)。クラスへの多くの参照が存在します。

このコンテキストによると、オブジェクトへの複数の参照がある場合、オブジェクトの破棄をどのように処理できますか? または、相互に複雑な参照がある場合、メモリをどのように管理する必要がありますか?

4

5 に答える 5

17

追跡する

このコンテキストによると、オブジェクトへの複数の参照がある場合、オブジェクトの破棄をどのように処理できますか?

これらの参照がもう必要ないことを確認することによって。

それらを分離すると、使用されていないオブジェクトがメイン プログラムに接続されていない大きな分離グラフであっても、それらはすべてガベージ コレクションの対象になります

スコープの終わりに達したローカル変数は、ガベージ コレクションの対象となります (また、含まれているオブジェクトもそうです)、それらが他のオブジェクトに "リンク" されていない場合 (コレクションに追加されたり、ac omposite などに追加されたりします...) . オブジェクト グラフの観点から判断するのが実際に困難な UI オブジェクトについては、それらを正しく破棄するか、ドキュメントを読んで自然に破棄されることを確認してください。

JVM での参照カウントの簡略図

「【GC】放っておいて!!」

または、相互に複雑な参照がある場合、メモリをどのように管理する必要がありますか?

メモリを「管理」することはできません。参照を簡単に管理できます。アイデアは、オブジェクトへの参照を持たないようにすることで、オブジェクトへの接続を「切断」することです。その後、GC がそれらを駆除するまで、それらはメモリ内に存在します。

GC をいじって強制的に何かをさせようとしないでください。それはかなり賢い獣であり、いくつかのリクエストに明示的に反応するように指示することはできますが、無視される可能性があります-通常は悪い考えです.GCを明示的に呼び出さないでください.理解できない場合はファイナライザーと明示的なnullを避けてください.それらの意味


あなたのコメントに答えるために注意してください

複数のコレクションまたはコンポジットに追加されたオブジェクトへの参照を単純に nullにするだけでは、コレクションの対象にはなりません。これを行うことで、参照を 1 つだけ null にすることができます

このオブジェクトへの参照を持つすべてのリストまたはコンテナからこのオブジェクトを削除する必要があります (基本的に、このオブジェクトを「忘れる」ようにします)。作成したオブジェクトへの「記憶」または「リンク」を持つオブジェクトがなくなると、そのオブジェクトはガベージ コレクターのグラフで孤立したアイテムになり、削除の候補になります。

面倒に聞こえるかもしれませんが、メモリを手動で管理する言語 (C または C++、最も明白な参照を 2 つ挙げるとします) から考えると、動的に割り当てられたオブジェクトへのポインターを解放および null すると、実際にそれらが破棄されます。 、ただし、リスト (またはコンテナー) から要素を削除する必要があります。そうしないと、null ポインターへの空のバケツのように表示されます。


参考文献

于 2012-07-10T00:14:29.837 に答える
6

Java ガベージ コレクションの要点は、何もする必要がないことです。ガベージ コレクションは自動的に行われます。

于 2012-07-10T00:11:56.440 に答える
1

GC に収集させたいすべてのリファレンスを に割り当てますnull

于 2012-07-10T00:14:32.873 に答える
1

あなたができることは、中級クラスを1つ作ることです。たとえば、クラス A のインスタンスがあり、そのインスタンスに対して多くの参照があり、それを削除したいが、多くの参照がそれを困難にしている場合、次のように実行できます。クラス A のインスタンスへの参照 (ある種のプロキシのようなもの)。これで、クラス B のインスタンスへの参照が多数ありますが、クラス A のインスタンスへの参照は 1 つだけです。これは簡単に削除でき、ガベージ コレクターはクラス A のインスタンスを収集します。

画像は、プロキシ (クラス B のインスタンス) を使用した場合の違いを示しています。ここでは、参照を 1 つだけ削除する必要があります。

ここに画像の説明を入力

于 2012-07-10T00:16:34.607 に答える
0

ほとんどの場合、GCは適切なタイミングで魔法をかけます。

たとえば、ビューがモデルを観察していて、ビューを破棄してモデルを保持したいという状況が発生する可能性があります。その場合、オブザーバーのコールバックオブジェクトを覚えて、ビューを非表示にするときにそれらを削除する必要があります。オブザーバーごとに特別なフィールドを用意する必要はありません。コールバックの登録を解除する一連のタスクで問題ありません。または、より複雑なことに、モデル上に一時的な間接参照のレイヤーを作成して、基になるモデルから解凍することができます。ある種の弱い参照を持つ奇妙なものを避けることをお勧めします。

おそらくjava.awt.Frameを使用するなど、ファイナライザーがある場合(または、ある種の弱いマップエビクションが必要な場合)、リソースとメモリホッグの間に間接層を作成して、単純に無効にすることができます。

于 2012-07-10T00:42:15.803 に答える