Engineering · 1 min read
執行環境:socket、container、stack、heap、cgo
GOMEMLIMIT 管得了 Go heap,管不了瀏覽器 sidecar,也看不見 cgo 的 malloc。你的程式跑在哪裡,決定了誰的記憶體你管得到。
GOMEMLIMIT管得了 Go heap,管不了瀏覽器 sidecar,也管不了 cgo 的 malloc。
你的程式跑在哪裡
- Socket = 網路對話的一端(IP + port);TCP connection = 兩個 socket 之間的開放管道。HTTP keep-alive = 重複利用同一條管道,這在 L4 負載均衡下會讓重試卡在同一台(keep-alive 讓重試卡在同一台)。
- L4 在連線建立時選一次目標;L7 每個 request 重新選。K8s Service 預設是 L4。
- Container = 應用 + 依賴,透過 cgroup 隔離 CPU/memory。Sidecar = 同一個 pod 裡的第二個 container,同生命週期,但各自的 process 和記憶體。
- Stack = 每個 goroutine 的暫存空間,return 時自動回收。Heap = 活得比 function 久的資料,GC 回收。
GOMEMLIMIT只管 heap。 - cgo / off-heap = Go 呼叫 C library(如 libvips),C 側的
malloc記憶體對 Go runtime 完全不可見。GOMEMLIMIT和GOMAXPROCS都管不到。
在這個 OOM 裡的角色
瀏覽器 sidecar 是同 pod 的另一個 process(OS 基礎詞彙),有自己的 2Gi 記憶體上限。Go 的 heap 才 256Mi,GOMEMLIMIT 設在 Go process 上,完全碰不到瀏覽器的記憶體(錯誤的修法)。
同一個 pod 不代表同一塊記憶體。sidecar 有自己的上限和自己的死法。
參考來源:
- https://beej.us/guide/bgnet/
- https://en.wikipedia.org/wiki/OSI_model
- https://kubernetes.io/docs/concepts/workloads/pods/
- https://pages.cs.wisc.edu/~remzi/OSTEP/
- https://pkg.go.dev/cmd/cgo
- https://go.dev/doc/gc-guide
Related: 參見OS 基礎詞彙、GOMAXPROCS 限制平行不限並發,或回到系列總覽。