1. 程式人生 > 其它 >【C# .Net GC】GC與終結器 Finalize

【C# .Net GC】GC與終結器 Finalize

設計一個型別時,出於以下幾個效能方面的原因,最好是避免使用Finalize方法。

  • 可終結的物件要花更長的時間來分配,因為指向它們的指標必須放到終結列表中(21.7節“終結操作揭祕”會更詳細地討論)。
  • 可終結的物件會提升到較老的代,這會增大記憶體壓力,並在垃圾回收器判定物件為垃圾時阻止回收物件的記憶體。除此之外,該物件直接或間接引用的所有物件也會被提升(21.14節“代”將討論提升和代的問題)。
  • 可終結的物件導致應用程式的執行速度變慢,這是因為每個物件在回收時,必須對它們進行額外的處理。

Finalize方法在垃圾回收結束時呼叫,有以下5種事件會導致開始垃圾回收。

第0代滿第0代滿時,垃圾回收會自動開始。該事件是目前導致 Finalize方法被呼叫的最常見的一種方式,因為隨著應用程式程式碼執行並分配新物件,這個事件會自然而然地發生
程式碼顯式呼叫System.GC的靜態方法Collect程式碼

可以顯式請求CLR執行垃圾回收。雖然 Microsoft強烈建議不要這樣做,但某些時候還是有必要的。
Windows報告記憶體不足 CLR內部使用Win32 CreateMemoryResourceNotification和QueryMemoryResourceNotification函式來監視系統的總體記憶體。如果Windows報告記憶體不足,CLR將強制執行垃圾回收,嘗試釋放已經死亡的物件,從而減小程序工作集的大小。
CLR解除安裝AppDomain一個AppDomain被解除安裝時,CLR認為該AppDomain中不再存在任何根,因此會對所有代的物件執行垃圾回收。第22章“CLR寄宿和AppDomain"將討論AppDomain。

CLR關閉
一個程序正常終止時(相對於從外部關閉,比如通過工作管理員關閉),CLR就會關閉。在關閉過程中,CLR會認為該程序中不存在任何根,因此會呼叫託管堆中的所有物件的Finalize方法。注意,CLR此時不會嘗試壓縮或釋放記憶體,因為整個程序都要終止,將由Windows負責回收程序的所有記憶體 。


程式設計是個人愛好