Go GC:Go 1.5 將會解決延遲問題
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 和執行時的問題。
在經濟上,有個詞叫良性迴圈 – 不同的事務之間互相促進。在過去的技術界,軟硬體的開發也曾近有類似的良性迴圈。隨著 CPU 硬體的升級,執行更快的軟體被開發出來,這又促使 CPU 的速度和計算能力進一步的提升。在 2004 年左右,隨著摩爾定理的終止,這個良性迴圈也結束了。
現在,更多的電晶體不會帶來更快的速度。更多的電晶體意味著更多的核,但是軟體還不能完全發揮多核的效能。因為今天的軟體不能讓多核全部跑起來,那些搞硬體的就不會在 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:
- 成千上萬的 goroutines
- 錄音聲道的同步
- 執行 go 的執行時間,使 go 和使用者同步
- 空間位置的控制 (可以嵌入結構,內部指標 (&foo.field))
Java:
- 數以萬計的Java執行緒
- 物件/鎖定器的同步
- 執行C的執行時間
- 物件連線指標
最大的區別在於空間位置的問題。 在Java中, 一切都是指標,然而 Go 能夠讓你線上程中嵌入另一個執行緒。以下的多層指標嚴重地導致了垃圾回收器的很多問題。
GC 基本知識
下面是一個關於垃圾回收器的快速入門,它們通常涉及2個階段。
- 掃描階段:在堆中確定哪些東西是可獲得的。 這涉及到堆、快取器、全域性變數的指標的開始,到這些指標進入到棧。
- 標記階段:繞指標一圈。在你讀取的程式中儘可能標記出物件。從 GC 的角度來說, 當標記的段落併發的時候,指標還沒有改變,要終止它是最簡單的。GC 真正地併發是非常難的,因為指標是不斷改變的。 程式使用被稱為執行障礙的一些東西去關聯 GC,但是它並不會回收物件。 在實踐中, 寫屏障會比暫停回收器昂貴。
Go GC
Go GC 的演算法是使用寫屏障和短時間暫停的組合。下面是它的執行過程:
以下是 GC 演算法在 Go 1.4 執行的情況:
以下是在 Go1.5 的情況:
注意回收器的短時間暫停。 在GC的併發期間,GC佔據了25%的CPU.
以下是基準測試程式數值:
在Go的早期版本中,GC暫停一般比較長久, 它們隨著堆的增長而增長。 在Go 1.5中,GC 暫停比以往的短數量級多。
放大時,在堆記憶體與 GC 暫停間是有一點正相關的。但是它們知道問題在哪裡,並且將會在 Go1.6 中處理掉。
新的 GC 演算法有輕微的吞吐量處罰,當堆記憶體增長時處罰收縮。
未來
告訴大家,自從 Go 有了低延遲GC,GC 已經不再是問題。未來,開發團隊計劃讓 GC 變得延遲更低、吞吐量更高、更有預見性。他們會很好的平衡這些需求。Go 1.6 的開發工作,將由用例和反饋來驅動,所以大家有什麼需求的話,請讓他們知道。
新的低延時 GC 將使 Go 在更多方面替代手動記憶體管理語言,比如C。
問答
問:有堆壓縮的計劃嗎?
答:我們已經在計劃中接納了這項技術,它過去在 C 語言社群工作得很好。當在同一片記憶體裡,存放同樣大小物件時,這項技術可以避免產生大量碎片。
相關文章
- Google 怎麼解決長尾延遲問題Go
- 怎麼解決伺服器延遲問題伺服器
- 《RabbitMQ》| 解決訊息延遲和堆積問題MQ
- 解決 go get 超時問題Go
- 疫情延遲 題解
- 美國伺服器延遲高怎麼辦,如何解決延遲問題伺服器
- GO 問題之多版本衝突解決Go
- 兄弟連go教程(15)函式 - 延遲呼叫Go函式
- 伺服器延遲問題如何解決伺服器
- Go 解決國內go get安裝包超時問題Go
- MySQL主從資料庫同步延遲問題怎麼解決MySql資料庫
- MongoDB從庫延遲讀取資料問題的解決思路MongoDB
- 國內的 go get 問題的解決 --gopmGo
- go 學習筆記之解讀什麼是defer延遲函式Go筆記函式
- win7系統網路延遲問題多種解決方法Win7
- 安裝go 1.5 & 部署Go
- go-zero 如何應對海量定時/延遲任務?Go
- HTTP 請求延遲解決方案HTTP
- Go 模組存在的意義與解決的問題Go
- GO Modules的理解和遇到的問題解決方法Go
- 分析伺服器延遲的問題伺服器
- MySQL 8.0能徹底解決困擾運維的複製延遲問題!MySql運維
- go channel問題Go
- 使用OpenTracing跟蹤Go中的HTTP請求延遲GoHTTP
- 教你如何解決MySQL資料延遲跳動的問題MySql
- Go etcd 的依賴問題終於解決了。。。Go
- 使用go的併發性來解決Hilbert酒店問題Go
- 解決 go get github.com/kotakanbe/go-cve-dictionary下載中遇到的問題GoGithub
- MySQL之 從複製延遲問題排查MySql
- Go GC 機制的大坑GoGC
- Go的http庫處理multipart的兩個問題解決GoHTTP
- MySQL主從複製延遲解決方案MySql
- Go1.5 釋出說明Go
- API返回延遲,FPM重啟後恢復之後又重現 問題解決方案API
- Go Mysql Driver 整合 Seata-Golang 解決分散式事務問題MySqlGolang分散式
- golang windows10下 go build 無法編譯 問題解決GolangWindowsUI編譯
- 『開源』大半夜除錯TCP延遲問題除錯TCP
- GO的GC辣雞回收(一)GoGC