閱讀861 返回首頁    go 阿裏雲 go 技術社區[雲棲]


關於將臨時變量置為null是否有助於快速垃圾回收

“將不再使用的臨時變量立即置為null是否有助於垃圾回收”的話題好像有不少人爭論過。

首先,我們要理解GC回收垃圾數據的標準是通過路徑檢查,看是否還有引用指向某個對象。如果不再有引用指向這個待回收的對象,那麼GC會將其放入待回收隊列。從這個理論上來說,適時將不再使用的變量置為null是有助於垃圾回收的。但是,進一步理解GC的工作模式,我們會發現如下幾個問題。

1. GC隻是將其置於待回收隊列,並不一定立即回收(需要一定的條件)。
2. GC並不會在變量置為null時啟動回收動作。

所以隻有在某個理想狀態下,這個null才有助於GC回收。因此我個人並不推薦這樣的編碼方式,無論從代碼的優雅性還是效率上都無助於性能提升。當然對於非常消耗資源的對象,建議使用IDisposable接口和using關鍵字。

 

關於GC的一些補充:

1. GC隻回收托管堆上的對象。
2. 每個應用程序都有一些根,諸如全局變量或者靜態變量。
3. GC通過遍曆所有的根來檢查所有對象是否可達,從而判斷哪些對象依然被引用,其餘的則是可回收對象。
4. GC會尋找較大的連續可回收區塊,並將其他一些非垃圾對象搬移到此處,從而壓縮托管堆。
5. GC隻有在0代對象充滿、內存不足或者調用Collect方法時才會執行回收動作,以避免頻繁回收造成性能損傷。
6. CLR托管堆支持3個代齡:第0代,第1代,第2代。每級代齡都有一定大小的闕值。
7. 剛初始化的托管堆,所包含的對象都是第0代。當分配的對象超過了第0代設定的闕值時,會進行垃圾回收,並把存活的對象提升為第1代對象,第0代空缺。隨著程序運行,繼續分配第0代對象,當超過闕值時執行第2次垃圾回收,在回收前會檢查第1代闕值是否超出,如果超出則先回收第1代對象中可回收垃圾,並將存活下來的對象提升為第2代齡對象。然後繼續回收第0代,並相應地將第0代生存下來的對象提升為第1代齡對象。如此反複,從而最大程度上回收那些第0代的活躍可回收對象,從而提高GC性能。
8. GC是自我調節的,會根據係統具體狀況調節不同代齡的闕值,以此來提高回收效率。

最後更新:2017-04-02 00:06:28

  上一篇:go sqlhelper使用指南
  下一篇:go 事件注冊與潛在隱患