2012-06-16 31 views
12

我有一個原生對象(C++),它具有指向受管對象(C#)的gcroot指針。本地和託管析構函數

class SomeNativeClass { 
    gcroot<SomeManagedClass ^> managedClass; 
}; 

問題 當我刪除了這個類的本機代碼delete(someNativeClass)我以前分配,將managedClass實例被垃圾收集或者我應該明確地將其刪除(在本地析構函數)的原生性實例,以及?

+2

您不能刪除託管對象,只有垃圾收集器可以做到這一點。如果C#類實現了IDisposable,那麼您可能需要努力調用其Dispose()方法。 –

+0

@HansPassant感謝您的回答。如果只刪除本地對象,並且其他地方不引用託管,它是否會被垃圾收集? – GETah

回答

9

如果只刪除本地對象,並且託管在其他地方沒有被引用,它會被垃圾收集嗎?

這就是垃圾收集的本質。收集器在找不到對象的引用時會銷燬對象。當你使用gcroot模板類時,收集器找到對被管理對象的引用的「正常」方式是通過在cpu寄存器中發現它們以及託管代碼堆棧和託管堆來實現的。這不能在本機代碼中工作,gcroot幫助。

gcroot構造函數調用GCHandle :: Alloc()來爲對象分配一個明確的引用。它的析構函數調用GCHandle :: Free()來刪除它。能夠分配這些「跟蹤句柄」是CLR中的一種輔助機制,它爲他們維護一個表格,表明收集器除了查找它自己的參考資料之外還要諮詢它們。最後的結果是,當你的類的析構函數運行時,它會自動調用gcroot析構函數。對象引用消失了。如果這是唯一的參考,在這種情況下很有可能,下一次垃圾收集掃描會破壞對象。自動。後來。

+0

+1感謝您的詳細解答 – GETah