1

當設置一Monotouch.Dialog實例:資料 - 單 - 其他根逆參考

  • 定製UIBubbleMapElement元件由GC設置;
  • 對於每個處置元素,自定義UIBubbleMapCell也被GC處置;
  • 但是對於所有處理過的單元,它們的自定義UIBubbleMapView都沒有處理。

要解決此問題,我開始使用Mono Profiler應用程序。

Mono profiler showing only a root reference.

的問題是:尋找在不設置UIBubbleMapView實例逆引用圖像。我怎麼能釋放這最後的參考,並允許收集我的自定義視圖?

最後,這是我UIBubbleMapCell Dispose方法:

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; 

雖然接收控制檯內部的下一個消息,單聲道分析器仍然呈現所述對象作爲未收集。與以前相同的圖像。

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

在API中運行時,我可以看到它的引用計數大於1。

Visible memory leak.

在圖像有一個UIBubbleTextView實例,但是它在相同的方式UIBubbleMapView情況下的行爲完全。我的UIBubbleMapView擁有一些其他意見。這是反向引用未檢查時的分析器信息。是否有一些技巧來處理這些子視圖?

No inverse references

回答

3

<Other Root>通常是一個的GCHandle Xamarin.iOS內部使用,以保持管理對象的生命,直到相應的原生對象被釋放。打破這個鏈接的一種方法是在對象上調用Dispose(你沒有提到在UIBubbleMapView上調用Dispose),在這種情況下,託管對象將被GC收集(除非它被其他託管代碼引用)。

很可能有一些其他本地代碼持有對此UIBubbleMapView實例的引用,但是要準確找出發生了什麼,您需要使用樂器中的分配工具進行配置文件(啓用參考計數跟蹤來精確跟蹤哪些代碼保留該物體)。

更新

直到你調用Dispose被管理對象,管理對象將保留原生對象[1]。這意味着如果保留計數大於1,那麼該對象還有額外的本地保留(這也意味着一旦您在對象上調用Dispose,其餘的引用都是本地的)。請注意,此時託管對象可能由GC收集,因此您不能使用HeapShot跟蹤(本機)對象,您必須使用Instruments。

提示:如果您在Instruments中啓用了右側邊欄,則會得到每個保留/釋放調用的堆棧跟蹤。這對追蹤誰保留對象非常有用。

[1] Xamarin.iOS也將釋放被管理對象一旦保留計數達到1時的引用(並且GC已確定管理對象未從其他託管代碼引用)。