golang 的 runtime 在 golang 中的地位類似於 Java 的虛擬機,不過 go runtime 不是虛擬機. golang 程序生成可執行文件在指定平臺上即可運行,效率很高, 它和 c/c++ 一樣編譯出來的是二進制可執行文件. 我們知道運行 golang 的程序並不需要主機安裝有類似 Java 虛擬機之類的東西,那是因爲在編譯時,golang 會將 runtime 部分代碼鏈接進去.
golang 的 runtime 核心功能包括以下內容:
下圖 1 是 golang 程序、runtime、可執行文件與操作系統之間的關係. 區別於 Java 需要安裝虛擬機,go 語言的可執行文件已經包含了 golang 的 runtime,它爲用戶的 go 程序提供協程調度、內存分配、垃圾回收等功能.此外還會與系統內核進行交互,從而真正的利用好 CPU 等資源. 本文主要簡單介紹 golang runtime 的併發調度模型、垃圾回收與內存分配.
調度是操作系統的核心功能了,從計算機誕生以來,任務的調度就一直在不斷改進與發展,以不斷適應計算機的發展. 單任務、多任務、併發、並行等調度. 到如今雲計算時代分佈式調度也十分成熟,由 go 編寫的 kubernetes 已經廣泛用於各個公司的分佈式集羣中.
golang 語言相比其它語言有一個特殊之處,它實現了自己的調度模塊,並不完全是由計算機操作系統進行調度的(進程、線程). golang 原生支持協程 goroutine,區別於線程、進程. goroutine 的調度由 go runtime 進行,這也是 golang 併發效率高的原因之一.
go 在處理協程上,使用了 GPM 調度模型,從而支持高效的併發調度. 如下圖 2 ,內核線程與邏輯處理器是多對多的關係即 M:N. 從而提升併發效率. GPM 各個模塊的解釋如下:
垃圾回收機制是編程語言的重要部分,它影響到程序的長久穩定運行. Java、Python 等語言都有自己的垃圾回收機制,而不需要像 c/c++一樣由程序員管理,可以避免大量的內存泄漏.
golang 的垃圾回收是基於標記清掃算法,這種算法需要進行 STW(stop the world),這個過程就會導致程序是卡頓的,頻繁的 GC 會嚴重影響程序性能. golang 在此基礎上進行了改進,通過三色標記清掃法與寫屏障來減少 STW 的時間.
三色標記法的流程如下,它將對象通過白、灰、黑進行標記,參考下圖3的動圖過程:
三色標記法相對於普通標記清掃,減少了 STW 時間. 這主要得益於標記過程是 「on-the-fly」 的,在標記過程中是不需要 STW 的,它與程序是併發執行的,這就大大縮短了 STW 的時間.
當標記和程序是併發執行的,這就會造成一個問題. 在標記過程中,有新的引用產生,可能會導致誤清掃,即將被清掃的標記爲黑色的對象引用了白色的對象. 這就需要用到屏障技術,golang 採用了寫屏障,作用就是爲了避免這類誤清掃問題. 寫屏障即在內存寫操作前,維護一個約束,從而確保將被清掃的黑色對象不能引用白色對象.
Tcmalloc(Thread Caching Malloc) 是 google 爲 c 語言開發的運行時內存分配算法. 其核心思想是多級管理,從而降低鎖的粒度. Go runtime 的內存分配就採用了 Tcmalloc 算法.
Go 程序在啓動時,會首先向系統申請一塊內存(虛擬地址空間),然後自己切成小塊進行管理. 將申請的內存,分成 3 個區域,spans、bitmap、arena,如下圖4,這三個區域的作用如下.
深入淺出Golang Runtime[https://zhuanlan.zhihu.com/p/95056679]
golang中的runtime包教程[https://studygolang.com/articles/13994?fr=sidebar]
Go垃圾回收機制剖析[http://www.pianshen.com/article/168671039/]
12 Go 併發調度器模型[https://www.jianshu.com/p/5df0a7e118d8]
三色標記[https://studygolang.com/articles/12062]
圖解Go語言內存分配[https://zhuanlan.zhihu.com/p/59125443]
圖解 TCMalloc[https://zhuanlan.zhihu.com/p/29216091]
Visualizing memory management in Golang[https://deepu.tech/memory-management-in-golang/]
Go: What Does a Goroutine Switch Actually Involve?[https://medium.com/a-journey-with-go/go-what-does-a-goroutine-switch-actually-involve-394c202dddb7]