1. 程式人生 > >試著把.net的GC講清楚(3)

試著把.net的GC講清楚(3)

優化 OS class 為什麽 特點 http com 我們 finalize

  • 試著把.net的GC講清楚(1)
  • 試著把.net的GC講清楚(2)
    前兩篇寫的都是gc的一些概念和細節,這些東西對自己以後寫代碼有什麽用,本篇我就準備將這些內容。

root

第一篇文章中講了GC在遍歷存活對象的時候,都是從root開始的,root是一些對象的引用,例如:全局對象、靜態對象等。

如果要減少root的個數,那麽就可以從靜態對象入手,減少靜態對象,畢竟靜態對象一直存活到程序結束。

全局對象為什麽不考慮?原因很簡單,就是靜態對象更容易優化,全局對象的一個程序中也沒有幾個,如果優化過程中,必然需要把全局對象的內容放到其它的地方,例如塞到另一個類裏面,那麽會造成這個類膨脹起來。
當然這也是一種方法。

LOH

之前了解到>=85000個字節的對象,會放到大對象的堆裏面,並且在gen2回收的時候才進行回收,且不進行內存壓縮,內存稍緊張的時候,就會造成少許浪費,所以
這個我們需要控制對象的體積,讓它盡可能<85000。

gen0、gen1、gen2

當gc觸發回收gen0的時候,那麽此次存活的對象會升代,理想情況讓gen0的大小在一次回收過程中,就可以得到內存空間,也就是需要減少一個對象的生存周期,讓對象的生存周期盡可能短。

在生存周期非常短的情況,那麽gen0的回收一次會獲取很大的內存空間,且升代的對象非常少,那麽gc就沒有必要再向OS申請內存資源了。

gc申請內存資源

在創建對象的時候,gc在自己可用內存不夠的情況下,會向os申請新的內存資源,並在gc回收內存後,並不會返回內存給os。所以就如之前的前一節說的,減少對象

可以讓os有更多的可調配資源。

Weak Reference

在GC回收的時候,weak reference的對象是會被當做垃圾的,所以這個慎用,基於這個特性,在某些場景下,weak reference的對象在使用的時候可以進行判斷是否已經被回收。
如果回收了,那麽重新在申請,比如某些占內存的外部資源,就可以使用weak reference來減少內存緊張帶來的問題。

finalize方法

還記得一個對象含有finalize方法的特點嗎?需要GC兩次才可能被回收,且GC的時間不定,所以非托管資源盡可能不使用finalize,對於內存緊張的情況,就不要使用了,不然
需要2次gc,gc的時候程序性能特別差。

workstation、server gc mode

保守的資源用workstation gc mode,非保守的資源用server gc mode,然後在用用cocurrent方式提升一下gc的性能,減少程序執行掛起時間。

總結

用理論指導實際,需要場景來支持,現在很多的程序的各種結構和算法都是為了提高性能而設計的,所以為了性能,很多的架構或者程序算法還有其他的輔助功能,也是很合理了。

試著把.net的GC講清楚(3)