Go GC:Go 1.5 將會解決延遲問題

oschina發表於2015-07-19

Richard L. Hudson (Rick) 是記憶體管理方面的專家,發明了 Train, Sapphire(http://people.cs.umass.edu/~moss/papers/jgrande-2001-sapphire.pdf), 和 Mississippi Delta 等演算法,其中 GC stack maps 演算法使靜態型別語言(比如:Java,C#, Go)的垃圾收整合為可能。他發表了很多關於語言執行時記憶體管理、併發、並行、記憶體模型、事務記憶體的文章。Rick 是 Google Go 團隊的一員,並負責 Go 的 GC 和執行時的問題。

Go GC:Go 1.5 將會解決延遲問題

在經濟上,有個詞叫良性迴圈 – 不同的事務之間互相促進。在過去的技術界,軟硬體的開發也曾近有類似的良性迴圈。隨著 CPU 硬體的升級,執行更快的軟體被開發出來,這又促使 CPU 的速度和計算能力進一步的提升。在 2004 年左右,隨著摩爾定理的終止,這個良性迴圈也結束了。

Go GC:Go 1.5 將會解決延遲問題

現在,更多的電晶體不會帶來更快的速度。更多的電晶體意味著更多的核,但是軟體還不能完全發揮多核的效能。因為今天的軟體不能讓多核全部跑起來,那些搞硬體的就不會在 CPU 中整合更多的核。迴圈被破壞了。

Go 的一個長期目標就是通過提供更多的並行、併發程式來重啟這個迴圈。短期內,我們要做的是提高 Go 的使用率。目前 Go 執行時遇到的最大的問題是 GC 暫停時間太長。

當他的團隊開始接手這個問題,他像其它工程師一樣開玩笑說,他們最開始的反應不是為了解決這個問題,而是這樣解決問題:

  • 新增一個監控器,不停的跟蹤計算機和 GC
  • 當 GC、網路延時、等怪情況發生時,發出一個網路等待標誌

但是 Russ Cox 否決了這些想法,所以他們決定挽起袖子好好的努力提升 Go 的 GC。他們開發的演算法會犧牲程式的執行能力來減少 GC 延遲。也就是說為了實現更低的 GC 延遲,Go 程式會比以前跑的稍微慢一點。

怎樣使延遲具體化?

  • 納秒: Grace Hopper 用距離類推時間。 一納秒等於11.8英寸。
  • 微秒: 光在真空中走1英里所用的時間就是5.4微秒。
  • 毫秒
  • 1:從 SSD 中連續的讀取1MB記憶體
  • 20:從副產品磁碟中讀取1MB記憶體
  • 50:感性的因果關係 (眼睛/游標 響應的臨界點).
  • 50+: 各種各樣的網路延遲
  • 300: 眨眼

所以我們能夠在1毫秒的時間內做多少 GC?

Java GC vs. Go GC

Go GC:Go 1.5 將會解決延遲問題

Go:

  • 成千上萬的 goroutines
  • 錄音聲道的同步
  • 執行 go 的執行時間,使 go 和使用者同步
  • 空間位置的控制 (可以嵌入結構,內部指標 (&foo.field))

Java:

  • 數以萬計的Java執行緒
  • 物件/鎖定器的同步
  • 執行C的執行時間
  • 物件連線指標

最大的區別在於空間位置的問題。 在Java中, 一切都是指標,然而 Go 能夠讓你線上程中嵌入另一個執行緒。以下的多層指標嚴重地導致了垃圾回收器的很多問題。

GC 基本知識

下面是一個關於垃圾回收器的快速入門,它們通常涉及2個階段。

Go GC:Go 1.5 將會解決延遲問題

  1. 掃描階段:在堆中確定哪些東西是可獲得的。 這涉及到堆、快取器、全域性變數的指標的開始,到這些指標進入到棧。
  2. 標記階段:繞指標一圈。在你讀取的程式中儘可能標記出物件。從 GC 的角度來說, 當標記的段落併發的時候,指標還沒有改變,要終止它是最簡單的。GC 真正地併發是非常難的,因為指標是不斷改變的。 程式使用被稱為執行障礙的一些東西去關聯 GC,但是它並不會回收物件。 在實踐中, 寫屏障會比暫停回收器昂貴。

Go GC

Go GC 的演算法是使用寫屏障和短時間暫停的組合。下面是它的執行過程:

Go GC:Go 1.5 將會解決延遲問題

以下是 GC 演算法在 Go 1.4 執行的情況:

Go GC:Go 1.5 將會解決延遲問題

以下是在 Go1.5 的情況:

Go GC:Go 1.5 將會解決延遲問題

注意回收器的短時間暫停。 在GC的併發期間,GC佔據了25%的CPU.

以下是基準測試程式數值:

Go GC:Go 1.5 將會解決延遲問題

在Go的早期版本中,GC暫停一般比較長久, 它們隨著堆的增長而增長。 在Go 1.5中,GC 暫停比以往的短數量級多。

放大時,在堆記憶體與 GC 暫停間是有一點正相關的。但是它們知道問題在哪裡,並且將會在 Go1.6 中處理掉。

Go GC:Go 1.5 將會解決延遲問題

新的 GC 演算法有輕微的吞吐量處罰,當堆記憶體增長時處罰收縮。

Go GC:Go 1.5 將會解決延遲問題

未來

告訴大家,自從  Go 有了低延遲GC,GC 已經不再是問題。未來,開發團隊計劃讓 GC 變得延遲更低、吞吐量更高、更有預見性。他們會很好的平衡這些需求。Go 1.6 的開發工作,將由用例和反饋來驅動,所以大家有什麼需求的話,請讓他們知道。

Go GC:Go 1.5 將會解決延遲問題

新的低延時 GC 將使 Go 在更多方面替代手動記憶體管理語言,比如C。

問答

問:有堆壓縮的計劃嗎?
答:我們已經在計劃中接納了這項技術,它過去在 C 語言社群工作得很好。當在同一片記憶體裡,存放同樣大小物件時,這項技術可以避免產生大量碎片。

相關文章