GO的垃圾回收器
#go語言垃圾回收整體採用的是經典的mark and sweep演算法。 中中(建議學習:go)
1.3版本,golang的超過閾值或定期如2min),暫停所有任務的執行,進行mark&sweep操作,操作完成後啟動所有任務的執行。
在記憶體使用較多的場景下,go程式在進行垃圾回收時會發生非常明顯的卡頓現象(Stop The World)。在對反應速度要求較高的後台服務進程中,這種延遲簡直是不能忍受的!這個時期國內外很多在生產環境實踐go語言的團隊都或多或少踩過gc的坑。
當時解決這個問題比較常用的方法是盡快控制自動分配記憶體的記憶體數量以減少gc負荷,同時採用手動管理記憶體的方法處理需要大量及高頻分配記憶體的場景。
1.3版本開始go team開始對gc性能進行持續的改進和優化,每個新版的go發佈時gc改進都成為大家備受關注的要點。
1.3版本中,go runtime分離了mark和sweep操作,和以前一樣,也是先暫停所有任務執行並啟動mark,mark完成後馬上就重新啟動被暫停的任務了,而是讓sweep任務和普通協程任務一樣並行的和其他任務一起執行。
如果運行在多核心處理器上,go會試圖將gc任務放到單獨的核心上運行而盡量不影響業務程式碼的執行。 go team自己的說法是減少了50%-70%的暫停時間。
1.4版本(目前最新穩定版)對gc的效能改變並不多。 1.4版本中runtime很多程式碼取代了原生c語言實作而採用了go語言實現,對gc帶來的一大改變是可以是實現精確的gc。
c語言實現在gc時無法獲取到內存的對象信息,因此無法準確區分普通變量和指針,只能將普通變量當做指針,如果碰巧這個普通變量指向的空間有其他對象,那這個物件就不會被回收。
而go語言實作是完全知道物件的類型訊息,在標記時只會遍歷指標指向的對象,這樣就避免了C實作時的堆記憶體浪費(解決約10-30%)。
1.5版本go team對gc又進行了比較大的改進(1.4中已經埋下伏筆如write barrier的引入),官方的主要目標是減少延遲。 go 1.5正在實現的垃圾回收器是「非分代的、非移動的、並發的、三色的標記清除垃圾收集器」。
分代演算法上文已經提及,是一種比較好的垃圾回收管理策略,然1.5版本中並未考慮實現;我猜測的原因是步子不能邁太大,得逐步改進,go官方也表示會在1.6版的gc優化中考慮。
同時引入了上文介紹的三色標記法,這種方法的mark操作是可以漸進執行的而不需每次都掃描整個記憶體空間,可以減少stop the world的時間。
由此可以看到,一路走來直到1.5版本,go的垃圾回收性能也是一直在提升,但是相對成熟的垃圾回收系統(如java jvm和javascript v8),go需要優化的路徑還很長(但是相信未來一定是美好的~)。
以上是golang 有gc嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!