Go 語言的垃圾回收演化歷程:垃圾回收和運行時問題
Google Go 團隊的成員 Richard L. Hudson (Rick) 近日在 Go 的官方博客和大家分享了他在2018年6月18日國際內存管理研討會(ISMM)上發表的主題演講稿。在過去的25年里,ISMM 一直是發布內存管理和垃圾回收論文的首選場所,而 Rick 也因其在內存管理方面的工作而被大家熟知。
Rick 是內存管理方面的專家,發明了 Train, Sapphire 和 Mississippi Delta 等演算法,其中 GC stack maps 演算法使得靜態類型語言(比如:Modula-3, Java, C# 和 Go)的垃圾回收成為可能。他還發表了很多關於語言運行時內存管理、並發、並行、內存模型、事務內存的文章。Rick 作為 Google Go 團隊的一員,負責 Go 的 GC 和運行時的問題。
Risk 在演講稿中先是介紹了 Go GC 取得的成功。
Go 的應用程序中有數十萬個堆棧(stacks),它們由 Go scheduler 調度程序管理,並總是在 GC safepoints 處被搶佔。Go scheduler 調度程序將 Go routines 多路復用到 OS 線程上,希望每個 HW 線程使用一個 OS 線程來運行。通過複製它們並更新堆棧中的指針來管理堆棧及其大小,這是一個本地操作,因此它可以很好地擴展。
Go 語言包含兩大可調節的方法來控制 GC,一個是 SetGCPercent,另一個則是 SetMaxHeap。前者可以調整你想要使用多少 CPU 以及你想要使用多少內存。後者尚未發布但正在內部使用和評估,它允許程序員設置最大的堆內存大小應該是多少,MaxHeap 還提供了更多的調度靈活性,運行時(runtime)可以將堆的大小調整為 MaxHeap。
而對於 Go 語言的 GC 延遲問題,開發團隊為解決它們付出了巨大的心血。從2014年開始,最初的計劃是做一個無 read barrier 的並發複製GC,因為讀取的開銷存在很大的不確定性,所以 Go 想要避免它們。
但當時由於編譯器的性能限制所在,後來他們放棄了實現「複製」部分。
然後 Risk 談到了最終推動 GC 延遲問題走向成功的 GC Pacer,它確定何時最佳地啟動 GC 循環,當然它做的遠不止這些,這只是基本方法。
談到成功,自然也會有失敗。Risk 和大家分享了類似 ROC(Request Oriented Collecter) 這種方案的失敗嘗試,他們採用 ROC 方案後,發現這反而降低了 write barrier 的速度。
談到 Go 語言的未來方向方面,Risk 表示不打算增加 GC API surface,現在已經很合適,並且沒有一個應用程序重要到足以讓他們添加新標誌。他們還將研究如何改進已經非常好的逃逸分析並優化 Go 的「面向價值(value-oriented)」編程。不僅在編程中,還包括為用戶提供的工具中。在演算法上,將關注設計空間的一些部分。
最後,Risk 表示希望摩爾定律在接下來的5年中能更好的體現在 RAM 而不是 CPU。
OSC開源社區頭條號,每日推送最新優質的技術類文章,包括外文翻譯,軟體更新,技術博客等。歡迎關注osc開源社區頭條號,點擊「了解更多」閱讀原文章。
TAG:OSC開源社區 |