1

Monotouch.Dialog インスタンスを破棄する場合:

  • カスタムUIBubbleMapElement要素は GC によって破棄されます。
  • 破棄された要素ごとに、カスタムUIBubbleMapCellも GC によって破棄されます。
  • しかし、破棄されたすべてのセルについて、彼らの習慣UIBubbleMapViewはどれも破棄されていません。

この問題を解決するために、Mono Profiler アプリケーションの使用を開始しました。

ルート参照のみを表示する Mono プロファイラー。

問題は、破棄されていないUIBubbleMapViewインスタンスの逆参照イメージを見ることです。この最後の参照を解放して、カスタム ビューを収集できるようにするにはどうすればよいですか?

最後に、これは私のUIBubbleMapCell破棄方法です:

protected override void Dispose (bool disposing) {

    bubbleMapView = null;

    System.Diagnostics.Debug.WriteLine ("############# {0} 'Dispose' {1}.", this, disposing ? "invoked directly" : "called by the garbage collector finalizer");

    base.Dispose (disposing);
}

そして、これは私がコンソールに出力したものです:

############# <UIBubblesViewController: 0x152427c0> 'Dispose' called by the garbage collector finalizer.
############# <UIBubbleMapCell: 0x152b6a40; baseClass = UITableViewCell; frame = (0 195; 320 38); autoresize = W; layer = <CALayer: 0x152c65c0>> 'Dispose' called by the garbage collector finalizer.
############# <UIBubbleMapCell: 0x1524aba0; baseClass = UITableViewCell; frame = (0 35; 320 38); autoresize = W; layer = <CALayer: 0x152038f0>> 'Dispose' called by the garbage collector finalizer.
############# <UIBubbleMapCell: 0x17c91710; baseClass = UITableViewCell; frame = (0 233; 320 116); autoresize = W; layer = <CALayer: 0x152cbb80>> 'Dispose' called by the garbage collector finalizer.
############# <UIBubbleMapCell: 0x1520b2c0; baseClass = UITableViewCell; frame = (0 108; 320 52); autoresize = W; layer = <CALayer: 0x17c2fc30>> 'Dispose' called by the garbage collector finalizer.

編集:答えてくれてありがとうロルフ。

最初に、次のコードを UITableViewCell Dispose メソッドに追加しました。

bubbleMapView.Dispose ();
bubbleMapView = null;

コンソール内で次のメッセージを受信して​​も、Mono プロファイラーはまだオブジェクトを収集されていないと表示します。以前と同じ画像。

 ############# <UIBubbleMapView: 0x154af370; frame = (0 0; 1 1); layer = <CALayer: 0x154af0e0>> 'Dispose' invoked directly.

intruments アプリで実行すると、その参照カウントが 1 より大きいことがわかります。

目に見えるメモリ リーク。

画像にはUIBubbleTextViewインスタンスがありますが、インスタンスとまったく同じように動作しUIBubbleMapViewます。

UIBubbleMapViewはいくつかの他の見解を持っています。逆参照にチェックを入れていない場合のプロファイラー情報です。この種のサブビューを処理するためのトリックはありますか?

逆参照なし

4

1 に答える 1

3

これ<Other Root>は通常、Xamarin.iOS が内部的に使用する GCHandle であり、対応するネイティブ オブジェクトが解放されるまでマネージド オブジェクトを維持します。このリンクを解除する 1 つの方法は、オブジェクトで Dispose を呼び出すことです (UIBubbleMapView で Dispose を呼び出すことについては言及していません)。この場合、マネージド オブジェクトは GC によって収集されます (もちろん、他のマネージド コードによって参照されていない限り)。

ほとんどの場合、この UIBubbleMapView インスタンスへの参照を保持している他のネイティブ コードが存在しますが、Instruments の Allocation インストルメントを使用してプロファイリングする必要があることを正確に調べる必要があります (参照カウントの追跡を有効にして、どのコードがオブジェクトを保持しているかを正確に追跡します)。 .

アップデート

管理対象オブジェクトで Dispose を呼び出すまで、管理対象オブジェクトはネイティブ オブジェクトを保持します [1]。これは、保持カウントが 1 より大きい場合、そのオブジェクトに追加のネイティブ保持があることを意味します (オブジェクトで Dispose を呼び出すと、残りの参照はすべてネイティブになることも意味します)。この時点で、マネージド オブジェクトが GC によって収集される可能性があるため、HeapShot を使用して (ネイティブ) オブジェクトを追跡することはできなくなり、Instruments を使用する必要があることに注意してください。

ヒント: Instruments で右側のサイドバーを有効にすると、各保持/解放呼び出しのスタック トレースが取得されます。これは、誰がオブジェクトを保持しているかを追跡するのに非常に役立ちます。

[1] Xamarin.iOS は、保持カウントが 1 に達すると、マネージ オブジェクトが持つ参照も解放します (GC は、マネージ オブジェクトが他のマネージ コードから参照されていないと判断します)。

于 2013-03-05T14:08:43.990 に答える