Go 1.6 將進一步改進垃圾收集器
盡管Go 1.5剛剛發布,仍然相對較新,但是Go團隊已經在致力于改進其新的低延遲并發垃圾收集器,希望Go更適合新的應用領域。Google工程師Austin Clements和Rick Hudson如是說。
Go 1.5用新的垃圾收集器代替了原來的STW(stop-the-world) GC,解決了延遲問題。當負載較重時,每50ms,新的GC的活動時間可以控制在10ms以下,從而使Go程序在一般情況下能運行得更快些。在更極端的情況下,停頓可以從300ms降到4ms。
Go 1.6的目標是進一步穩定GC,并在以下幾個方面做出改進:
-
狀態協調(State coordination):Go 1.5 GC有個主要瓶頸是從Go 1.4繼承來的,源自其集中式的GC協調器(coordinator),這是一個單獨的goroutine,它會將工作進一步分派給worker goroutine去完成。一種解決方案是用去中心化的狀態機代替集中式協調器。這樣修改有個額外的好處,使得重新設計標記完成屏障(mark completion barrier)成為可能,因為它已經變得非常凌亂,而且性能很差。
-
信用系統(Credit system):Go 1.5在兩個不同的地方使用了一個信用系統:一個是確保清掃(sweeping)在一個GC周期和下一次觸發堆操作(the next heap trigger)之間完成,一個是確保掃描(scanning)在觸發堆操作(an heap trigger)和隨后實現堆處理目標之間完成。改進信用系統的一種建議方法是,使其操作總是在black階段進行,以避免未完成的分配操作進入下一個GC周期。
-
標記結束(Mark termination):根據Clements和Hudson的介紹,在Go 1.5中,標記結束階段是停頓時間的大頭。這里的目標是嘗試并確保大部分應用可以在10ms停頓的閾值下運行,這也是Go 1.5在很多情況下已經實現了的。希望所做修改的復雜度較低或中等,比如把finalizer掃描從標記結束階段移到并發掃描,這樣對于每1GB大小的堆,應該可以節省1ms,以及去掉一個成本很高的計數循環,對于較大的堆,這個循環占去了標記階段的另外一半。
-
sweeper和scavenger:某些程序會在sweeper上消耗大量時間,在這上面投入些精力,應該有性能改進。一個非常激進的方案是完全去掉sweeper。還有一個不那么激進的方案,可以在GC階段最后,盡早釋放較大的對象,并且在所有的系統上支持scavenger,不管物理頁面是多大。
上面只是對計劃所做改進的一個概覽,欲全面了解,可以閱讀原始文檔。文檔中還有進一步指向GitHub issues的鏈接,這些issues記錄 了每個改變背后的理由以及建議方案。
轉載自:infoq.com/cn