Data will become your king, but your king has no intention of keeping you around longer than needed. (資料將成為你的王, 但你的王無意讓你再被需要)
After years of traditional methods, Face ID became a reality mostly because of data feeding the machine not because of some super crafty algorithm. (在傳統方法的多年之後, FaceID之所以能成為現實, 主要在於餵給機器資料而非充滿多端詭計的演算法)
今年六月初的文章, 作者為了 Vilnius Go Meetup 所準備的分享, 蠻早就看到了這篇, 會 queue 到現在的主因在於文章末段並沒有回答開頭提出的問題: 為何一個簡單的 Go http server 範例記憶體使用會高達 380MB? 原以為近期可能會寫續章, 可惜的是等了一個半月沒有下文. 然而若細看了昨天所分享的 “Getting to Go” , 這個問題就不難推敲可能的因素, 因此就分享呼應昨日分享的 Go Garbage Collection 相關文章.
這篇內容值得推荐的地方在於, 為了弄清楚相關問題,把從 CPU 方面的 page management, OS 如何管理記憶體, 一路到 Process 內 Heap 與 Stack 的使用都做了交代. 是不錯的從做中學的範例, 另外提供了對系統整體性與層次上的了解.
文章大概在中間開始才開始進入重點, 藉由介紹 Memory Allocators (TCMalloc, ptmalloc2) 切入, 觸及到 Go Memory Allocator 對於記憶體管理上的行為, 說明 Go 是如何處理 tiny object,以及透過 mcache, mheap 與 mspan 三者與 runtime 中負責 OS 層的 mcentral 做記憶體的配置與管理.
文章末段,透過觀察了 runtime 的消耗, C 語言程式的基本用量, 系統關於 process 的資訊 (/proc, /proc/PID/maps), 以及與更簡單的 Go 程式相較.
若有稍微閱讀昨日分享的 “Getting to Go” 可能會聯想到一件事 — stacks of goroutine.使用了 Go routine 一般會有 100K+ 的 stack 的數量, 若平均一個 stack 只要有 4KB 的配置, 就可以消耗 > 400MB, 那麼要確認的就是 Go package 中 http server 是否使用了 goroutine? 查詢 Go 官方文件可以看到:
Serve accepts incoming HTTP connections on the listener l, creating a new service goroutine for each
這說明了 go http 套件中 server 實作上使用了 goroutine 來處理相關的 request.
副標其實是原文的標題, 一語雙關蠻有意思的, “Getting to Go”意思是 “出發吧”, 但因為裏面的 “Go” 又同時就是 Go 語言的名稱. 這是個關於 Go 語言中以 Garbage Collection 角度討論 Go 歷程的官方部落格文章.
這篇文章紀錄了作者自 2014 至今對 Go 內部 GC 的改進與一路至今的歷程. 通篇的主軸在於從 Garbage Collection 的角度來分析看待 Go 語言. 相當值得一讀!
首先作者希望大家知道的是 Go 程式通常使用著 100,000+ 以上的 stack.
這些 stack 是被 Go scheduler 所管理著, 並且總是會被 GC 在安全點時搶佔. Go scheduler 將 Go routines 混合運行在期望能對應到每個 HW thread 的 OS threads 之上.
第二件重要的事情是 Go 是個 value-oriented 的程式語言, 這點與 C 類似而與一般其他需要執行環境 (runtime) 的 reference-oriented 程式語言不同. 如此的設計也帶來外部函式介面(foreign function interface, FFI) 的好處. Go 有著快速的 FFI. 由於不可能將全系統重新以 Go 語言打造, 因此 Go 必須透過 FFI 來與存取外部系統. FFI 這一點帶來許多驚人的事情, 這同時也是讓 Go 與其他同樣有著 GC 功能的語言有著重大差異的一點.
語言特性上需要注意, Go 允許 interior pointer (指向結構內特定欄位的 pointer), 此外 Go 本身為 ahead-of-time 編譯的語言, binary 即包含環境, 並不需要 runtime 以及 JIT.
大致上了解這些後, 作者帶大家回顧 Go 在 2014 在當時的挑戰:
在 2014 年 Go 飽受 GC latency 之苦. 可以這麼說, 若在 2014 年那時 Go 無法解決 GC 帶來的 latency 問題, Go 無法取得廣泛的成功. 而在當時許多其他的語言(像是 Rust)也同樣面臨著 latency 的問題, 但為何 latency 如此地重要?
Cyberthreats 表示安全性不能是選擇性的.
專有產品能是嚴重不安全的, 因為他們無法受惠於開源開發者與業界專家多年的審查, Spectre 與 Meltdown 可能會對其發生. ARM 並不關心大眾期望的安全議題. 他們長時間忽略了 ret2usr
for a very long period of time, 當百萬計的 ARM 使用者暴露在這個龐大漏洞, 直到一些安全特性 (domain,
PXN) 加到了 ARMv7 中. 第一個 PXN 實作是
PaX/Grsecurity 所完成, 當第一個 implementation of domain 是 PaX's UDEREF 所完成. 至今 ARM 都沒有歸功於他們. RISC-V 將有機會在一開始做正確的事情, 而那是安全子團隊以及來自 RISC-V 基金會的 Security Standing Committee 從開始就已經在進行的.