2

.NET/Java では、ガベージ コレクターに関する魔法のプロパティを持つクラスで参照をラップできます (例: WeakReference など)。

「従わない」参照の考え方には、そのようなクラスはないようです。つまり、ガベージ コレクタに、指定された参照以降のオブジェクトの複雑なサブグラフがあり、それを収集すべきではないことを伝える方法です。(そのため、そのサブグラフのマークとスイープを行って CPU サイクルを無駄にしないでください)。

この機能がない理由を知っている人はいますか?

どうもありがとう

4

3 に答える 3

1

あなたが考えていることをしないので、その機能はありません。マーク アンド スイープ コレクターは、オブジェクト グラフを走査し、どのオブジェクトを保持する必要があるかを記録します。一部のサブグラフをマークしないように指示した場合、コレクターは、クリーンアップのために行ったすべてのことを行ったときに、それらのオブジェクトをすべて破棄します。有用な参照ステータスは、「keep this」(メイン クラスに固定されたグラフ内の参照を保持する)、「throw this away」(そこから到達可能な参照を保持しない)、および「これをスローするかどうかを選択できる」のみです。アウェイ」(WeakReference)。

于 2013-08-01T21:21:34.143 に答える
0

問題は、GC の設計が、すべてが死んでいると想定し、生きているオブジェクトを見つけてから、残りを収集することです。あなたのアイデアを機能させるには、アプローチを逆にして、すべてが生きている状態で GC を開始し、死んだオブジェクトを見つける必要があります。

このシナリオを考えてみましょう。オブジェクト A があります。これは、特別な「グラフをナビゲートしない」オブジェクトです。グラフは A->B->C になります。ライブ オブジェクトを検出する GC では、「グラフをナビゲートしない」フラグによって B と C が検出されなくなるため、B と C がアクティブであることを知る方法がありません。集めます。良くない。

では、なぜ GC は死んだオブジェクトではなく、生きているオブジェクトを検索するのでしょうか? 生きているオブジェクトを見つけるために、GC はまだ使用中であることがわかっている参照 (ルートと呼ばれる) から開始します。これらは通常、スタック上にある参照 (現在実行中のメソッドのローカル変数)、静的参照、およびその他のいくつかです。これらのルートによって参照され、グラフの最後まで再帰的にトレースされるすべてのオブジェクトは、確実にまだ使用されており、収集できません。それ以外はすべてゴミです。

逆のアプローチを実装し、すべてが生きていると仮定し、死んだオブジェクトを検索しようとした場合、ヒープ内のすべてのオブジェクトを見て、それを参照しているオブジェクトを見つけ、そのグラフがなくなるか見つかるまで追跡する必要があります。ルート。ルートが見つかった場合、チェーン内のすべてが生きています。そうでない場合、チェーン内のすべてが死んでいます。

2 つのアプローチの違いは、根から始める方がはるかに少ない作業で済むことです。あなたがフォローするすべての参照は生きていることが保証されています。オブジェクトは他の何千ものオブジェクトを参照しているかもしれませんが、そのオブジェクトと千のオブジェクトが生きていることを証明するには、ルートから 1 回通過するだけで済みます。逆に、ルートからそのオブジェクトにたどり着かない場合は、それらの何千もの参照をナビゲートすることなく、そのオブジェクトが死んでいることがわかります。

また、オブジェクトは、それらを参照するものではなく、参照するものを保存します。オブジェクトが与えられた場合、誰かがそれを参照しているかどうかを調べるには、他のすべてのオブジェクトの参照を検索する必要があります。または、各オブジェクトにレフリーのリストを保存することもできますが、各参照には 2 倍のメモリが必要です。

.Net には、ルートとして扱われる参照を作成できる GCHandle クラスがあります。したがって、オブジェクトのサブグラフは収集されません。ただし、これらのオブジェクトが何であるかを知るには、サブグラフをナビゲートする必要があります。

つまり、GC はシンプルさとパフォーマンスのためにこのように設計されています。オブジェクトのサブグラフをマーク/スイープしないと、サブグラフ内のオブジェクトがガベージ コレクションされる可能性があります。これはあなたが望むものの反対です。

于 2013-08-08T08:17:43.950 に答える
0

GC の動作を理解する最も簡単な方法は、ボウリング場に行って、プレーヤーが最初のボールを転がした後に何が起こるかを観察することです。マシンは、まだ立っているすべてのピンを識別し、それらをレーンから外し、やみくもにレーンをクリアしてから、立っていたピンをレーンに戻します。マシンは、どのピンが倒されたのか、何本倒されたのかは気にしません (ただし、10 個のピンすべてが倒された場合を除きます。この場合、次のフレームにすぐに進みます)。倒されたピンにタグを付ける手段があったとしても、そのようなタグ付けはピンセッターにとって少しも役に立ちません。

考慮すべきもう 1 つのことは、GC フレームワークの最も基本的な利点の 1 つは、ダングリング リファレンスなどがないことです。オブジェクトは、到達可能な参照がどこかに存在する限り存在し、到達可能な最後の参照が破棄されると存在しなくなります。弱参照などを可能にするために、システムは強参照を介して到達できるすべてのオブジェクトを識別することから始めます。それが完了すると、システムは弱参照のリストを調べて、ターゲットが有効としてマークされていない弱参照を無効にします。Finalizeまた、オブジェクトのリストを調べて、そのリストにあるが他のどこにも参照されていないアイテムをオーバーライドして追加し、すぐにクリーンアップする必要があるオブジェクトのリストに追加します。オーバーライドするオブジェクトFinalizeまたは、弱い参照が存在するものは、GC が何らかの手段でそれに到達する可能性のあるすべての参照を消去するまで存在し続けます。ただし、ほとんどのオブジェクトは、スペースを再利用するために GC がいつ実行されるかに関係なく、最後の参照が上書きされるとすぐに存在しなくなります。

于 2013-08-27T22:11:24.967 に答える