CLR via C# 讀書筆記 5-3 使用GC Handle手動控制對象生命周期
使用System.Runtime.InteropServices.GCHandle類來手動控制對象的生命周期
(個人感覺這里可能有一些問題...只是草稿而已..還請高手指正)
1.GCHandle.Alloc
傳遞一個Object和一個GCHandleType枚舉給Alloc方法以控制Object的生命周期,返回一個GCHandle
1) GCHandleType.Weak 此標志位允許你監視對象生命周期,當對象被標記為不可到達的時候,這個對象的Finalize方法可能執行也可能沒有執行,這個對象可能依然存在于內存中
2) GCHandleType.WeakTrackResurrection 此標志位允許你監視對象生命周期,對象的Finalize方法肯定會被執行(如果有的話),內存會被回收
3) GCHandleType.Nomal 此標志位允許你控制對象生命周期,保證對象一直存在,在GC的時候該對象可能被移動位置
4) GCHandleType.Pinned 此標志位允許你控制對象生命周期,保證對象一直存在,在GC的時候該對象不會被移動
2.GC和GCHandle的關系
GCHanlde 是一個輕量級的值類型,內部只包含一個實例Field:IntPtr
1) GC標記所有可到達的對象,然后GC掃描 GC Handle 表, 所有標記為Normal和Pinned的對象將被視為可到達的對象(包括這些對象的成員 這是一個遞歸的過程)
2) GC掃描GC Handle表中所有標記為Weak的實體,如果該實體所指向的Object被標記為不可到達的,(也就是標記為垃圾),那么這個擁有指針的實體將置為null
3) GC掃描終結列表(Finalization List 不知道怎么翻譯...),將所有指向不可到到達的指針移動到Freachable Queue,然后被指向的對象標記為可到達的
4) GC掃描GC Handle 表中所有標記為WeakTrackResurrection 的實體,如果該實體所指向的Object被標記為不可到達的,那么擁有這個指針的實體將置為null
5) GC Compact內存(當然有的時候GC不并執行這個動作,因為它覺得不值得),此外Pinned的對象不會被移動
3.應用
1) c# fixed關鍵字 就是GCHandleType.Pinned 的實際應用之一
2) Weak標記可以讓你知道什么時候一個對象已經決定被回收,(但是這個對象也許還沒有被回收)
3) WeakTrackResurrection標記可以讓你知道什么時候一個對象的內存被回收(按書中所說...這個東西好像沒啥用)
4) WeakReference其實就是對GCHandle的封裝
浙公網安備 33010602011771號