Skip to content
所有文章 ‹ Part 06 of 11 · 從 19 個 goroutine 到 exit 137
工程 · 1 min read

OOM 診斷決策樹:從 pprof 往下鑽

從最便宜的工具開始。一棵從 pprof 往 runtime 再往 cgroup 鑽的決策樹,定位 Go 服務吃記憶體的原因。

從最便宜的工具開始。pprof(Go 內建的 heap profiler,go tool pprof)解釋不了的,才往 runtime → cgroup 鑽。

決策樹

pprof inuse_space 大? YES function-level 兇手找到 NO heap_alloc 大? YES sampling 漏了;看 alloc_space NO runtime 差距: inuse−alloc 大? → 碎片 (散落活物件卡住 span) idle−released 大? → scavenger 延遲 都不大? → 比較 RSS vs cgroup: ├─ 接近 → process 內洩漏 └─ cgroup>>RSS → kernel memory (未關閉 socket、file cache)

三個層次

  1. App 層(pprof):inuse_space 看活物件的 function 歸屬。小的話,alloc_space 抓高頻配置(快速 alloc → GC → alloc,sample 時看不到但 total 很高)。
  2. Runtime 層(Go metrics):heap_inuse − heap_alloc = 碎片。heap_idle − heap_released = 分配器拿著沒還的(記憶體三層模型、分配器內部)。
  3. Kernel 層(cgroup):container_memory_usage_bytes − container_memory_rss = kernel-charged memory。大 = 未關閉 socket、file cache、kernel buffer。

在這個 OOM 裡的角色

這次 OOM 的兇手不在 Go heap。是瀏覽器 sidecar 的記憶體。這棵決策樹用來排除「Go 自己的問題」,確認問題在 process 外(共享資源的影響範圍)。

診斷工具的順序就是成本的順序:pprof(免費)→ runtime(低)→ cgroup(要 Prometheus)。

參考來源:

延伸閱讀: 參見記憶體三層模型、分配器內部、共享資源的影響範圍,或回到系列總覽。

↑↓ 移動 ↵ 開啟 esc 關閉