9

私が修正しているスライドでは、次のように述べています。

ライブ オブジェクトは、各オブジェクトへの参照の数を維持するか、ルートから参照のチェーンを追跡することによって識別できます。

参照カウントはコストがかかります。参照が変更されるたびにアクションが必要であり、循環構造を見つけることはできませんが、スペースを段階的に再利用できます。

トレースには、スペースを再利用する必要がある場合にのみ、ライブ オブジェクトを識別することが含まれます。一般的なアクセスから、通常はメモリが不足している場合にのみ、GC が実行される時間にコストを移動します。

参照カウントが高価である理由の原則は理解していますが、「循環構造を検出しないが、スペースを段階的に再利用できる」ものを理解していません。意味。誰か私を少し助けてくれませんか?

ありがとう

4

5 に答える 5

5

参照カウントは循環構造を検出しません...

O1 と O2 という 2 つのオブジェクトがあるとします。それらは相互に参照します: O1 -> O2 および O2 -> O1 であり、他のオブジェクトはそれらを参照しません。どちらも参照カウント 1 (1 つのリファラー) を持ちます。

O1 と O2 のどちらにも GC ルートから到達できない場合は、安全にガベージ コレクションを実行できます。どちらも参照カウント > 0 であるため、参照をカウントしてもこれは検出されません。

オブジェクトがガベージ コレクションの対象となるには、0 参照で十分ですが、必須ではありません。

...しかし、スペースを段階的に再利用できます。

増分部分とは、0 で参照されるオブジェクトの一部を迅速にガベージ コレクションし、中断して別の時間に問題なく続行できるという事実を指します。

トレース アルゴリズムが中断された場合、次にスケジュールされたときに最初からやり直す必要があります。(参照ツリーは開始時から変更されている可能性があります!)

于 2010-05-31T10:12:56.153 に答える
1
  1. A が B を参照し、B が A を参照する場合、単純な参照カウントでは解決できません。この場合、A と B の両方の参照カウントが 1 になり、他に参照がなくても収集されません。
  2. 参照カウントは、オブジェクトの参照カウンターが 0 になるとすぐにスペースを回収できます。GC サイクルを待機したり、他のオブジェクトをスキャンしたりする必要はありません。したがって、ある意味では、オブジェクトから 1 つずつスペースを回収するように段階的に機能します。
于 2010-05-31T10:13:24.623 に答える
1

「循環構造を見つけられない」

オブジェクトを持っているとしましょうA。その作業を行うためにA呼び出される別のオブジェクトが必要です。Bただし、その作業を行うためにB呼び出される別のオブジェクトが必要です。Cしかし、何らかの理由Cでポインタが必要です。Aしたがって、依存関係グラフは次のようになります。

A -> B -> C -> A

オブジェクトの参照カウントは、それを指している矢印の数でなければなりません。この例では、すべてのオブジェクトの参照カウントは 1 です。

メイン プログラムが実行中にこのような構造を作成し、メイン プログラムに へのポインタがAあり、Aのカウントが 2 になったとします。この構造が範囲外になるとどうなりますか? Aの参照カウントが 1 に減らされます。

しかし、注意してください!現在、、、AおよびBすべてCの参照カウントは 1ですが、メイン プログラムからはアクセスできません。したがって、これはメモリ リークです。ウィキペディアには、この問題を解決する方法の詳細があります。

「スペースを段階的に再利用できます」

ほとんどのガベージ コレクターには、実行を一時停止し、使用されなくなったオブジェクトを解放する収集期間があります。マーク アンド スイープ システムでは、これがスイープ ステップです。欠点は、スイープの間の期間中、メモリが増え続けていることです。オブジェクトは作成直後に使用されなくなることがありますが、次のスイープまで再利用されることはありません。

参照カウント システムでは、参照カウントがゼロになるとすぐにオブジェクトが解放されます。大きな一時停止や大きなスイープ ステップはありません。使用されなくなったオブジェクトは、コレクションを待つだけでなく、すぐに解放されます。したがって、コレクションは、最後のコレクション以降に使用されなくなったすべてのオブジェクトを一括収集するのではなく、使用されなくなったオブジェクトを増分的に収集するという点で増分的です

もちろん、この漸進主義には落とし穴があります。つまり、大量の小さな GC よりも大量の GC を実行する方がコストがかからない可能性がありますが、それは正確な実装によって決まります。

于 2010-05-31T10:19:33.730 に答える
0

3 つのオブジェクト (A、B、C) があるとします。A には B への参照があり、B には C への参照があり、C には A への参照があります。しかし、これらのいずれかへの参照を持つオブジェクトは他にありません。それは独立した循環構造です。従来の参照カウントを使用すると、すべてのオブジェクトが引き続き参照されるため、ガベージ コレクターがサイクルを削除できなくなります。しかし、誰も 3 つのうちの 1 つを参照していない限り、削除することができます/削除する必要があります。スペースを段階的に再利用するということは、参照されていないインスタンス、サイクルがないなどを見つけるときに参照カウントが機能する方法を意味すると思います。

于 2010-05-31T10:14:01.580 に答える
0

参照カウントが 0 になると、ガベージ コレクションのためにオブジェクトを解放できます。

循環参照の場合、円内の各オブジェクトが別のオブジェクトへの参照を保持するため、これは決して発生しないため、それらはすべて少なくとも 1 です。

そのためには、ヒープ海の小さな島のように、もはや何にも関連付けられていない参照を検出するためのグラフ理論が必要です。これらをメモリに保持するには、どこかに静的変数への「アタッチメント」が必要です。

それがトレースの機能です。ヒープのどの部分がアイランドで解放可能で、どの部分がまだメインランドにアタッチされているか、つまり静的変数がどこにあるかを判断します。

于 2010-05-31T10:16:12.000 に答える