blog

参照カウントGCの循環参照問題を解決するには?

I: ...参照カウントの循環参照問題は、強参照カウントと弱参照カウントを組み合わせることで解決できます。 spは強ポインタ強ポインタ参照、wpは弱ポインタ弱ポインタ参照。 Javaでは、オブジェクト...

Sep 14, 2020 · 3 min. read
シェア

GC 2011 の参照カウント法は、循環参照に悩まされ、不要なオブジェクトを識別することが 不可能になりますが、GC 2011 の ROOT メソッドは循環参照に悩まされることはありません。

ゴミ収集の仕組みについて教えてください

...循環参照問題は、強参照カウントと弱参照カウントを組み合わせることで解決できます。

スマートポインター

スマート・ポインターはAndroidプロジェクト全体で広く使われており、バインダー関連のソースコードではsp型やwp型への参照を見ることができます:

sp<IBinder> result = new BpBinder(handle); wp<IBinder> result = new BpBinder(handle);

spは強ポインター、wpは弱ポインター。

Javaでは、オブジェクトの破棄やメモリの解放を気にする必要はなく、GCメカニズムが自動的に無駄なオブジェクトを識別し、再要求します。 スマート・ポインタは 、ネイティブ・レベルでの小さなGC実装です。

スマートポインタは、参照カウントによって役に立たないオブジェクトを識別します。 スマートポインタを使用するオブジェクトは、オブジェクトへの強参照と弱参照の数を保持するRefBaseを継承します。

強ポインタspは"="演算子をオーバーロードし、他のオブジェクトを参照しているときは強参照を+1カウントし、spのデストラクタでは-1カウントし、強参照カウントが0になったときに参照オブジェクトを破棄します。

弱いポインタは、弱い参照カウントが+1の他のオブジェクトを参照し、wpデストラクタでは弱い参照カウントが-1になります。強い参照カウントが0の場合、弱い参照カウントが0であるかどうかに関係なく、参照されたオブジェクトは破棄されます。

円形参照の問題の解き方

強参照カウント法だけに頼ると、循環参照の問題が発生し、その結果、オブジェクトが解放されることがなくなりますが、弱参照は循環参照の問題を解決するために特別に設計されています:

AがBを強く参照する場合、BはAを弱い参照で参照します。オブジェクトが無駄かどうかを判断する場合、弱い参照の数はカウントされず、強い参照の数だけが0とみなされます

これは、循環参照がオブジェクトの未リリースを引き起こすという問題を解決しますが、ワイルド・ポインタの問題を引き起こす可能性があります。Bが弱いポインタを使ってAにアクセスしようとすると、Aはすでに破棄されている可能性があり、Aへの弱いポインタはワイルド・ポインタになります。この場合、Aはもう存在しないことになり、再作成などが必要になります。

スマートポインタカスタムルール

スマートポインタは、「強い参照カウントが0になったときに、弱い参照カウントが0であるかどうかに関係なく、参照オブジェクトを破棄する」固定ではなく、カスタマイズされたルールを設定することができます。 refBaseは、参照カウンタのルールを設定するために使用できるextendObjectLifetime()メソッドを提供し、異なるルールは、以下のように、ターゲットオブジェクトを削除するタイミングの判断のために異なっています。3種類のルール

オブジェクトのメモリー空間のストロングカウンターが0になったときのみ、オブジェクトは破棄されます。

オブジェクトのメモリ空間の強カウンタと弱カウンタの両方が0になったときのみ、オブジェクトは破棄されます。

両方のカウンタが0であろうとなかろうと、オブジェクトは破壊されません。つまり、通常のポインタと変わりませんが、手動でオブジェクトを解放する必要があります。

Read next

リートコードの問題を解く log-1.

整数の配列 nums とターゲットが与えられたとき、ターゲットに和を返す配列中の2つの整数を求め、それらの配列添え字を返します。 各入力は1つの答えに対応すると仮定できます。ただし、配列の同じ要素を 2 回使用することはできません。 スペース・フォー・タイム・アプローチを使用して、配列を 1 回トラバースして答えを見つけます。 まずハッシュテーブルを作成します。 キー...

Sep 14, 2020 · 2 min read