下面這份是給一線 SRE/DevOps 用的內存可觀測性作戰手冊,聚焦 free / vmstat / top / ps / pmap 等核心工具的指標語義、判讀邏輯與落地流程。目標:在 5 分鐘內定位 80% 的 Linux 內存異常。🚀
一、方法論:先定義問題,再選工具
- 三問法:
1)系統層:是否發生 <span style="color:red">內存壓力/回收過激/觸發 OOM</span>?
2)進程層:哪個進程在 <span style="color:red">持續增胖</span>(RSS/VSS 增長)?
3)對象層:是否是 <span style="color:red">堆內存泄漏</span>、<span style="color:red">mmap 大文件緩存</span> 或 <span style="color:red">頁緩存/Slab 膨脹</span>? - 讀數優先級:vmstat(全局動態)→ top/ps(定位進程)→ pmap(內存結構)→ /proc 輔助(meminfo、smaps)。
- 關鍵認知:<span style="color:red">“可用內存”不是 free 命令裏 Mem 的 free 列</span>,而是 available(綜合考慮 page cache 與回收潛力)。
二、系統層工具與判讀
1)free:快照視角
free -h
解釋:輸出物理內存與 swap 概覽。
-
Mem: used / free / buff/cache / available
- available ≈ 還能不觸發劇痛回收就供應用可用的內存。
- buff/cache 高 ≠ 內存不夠;是文件緩存,壓力來時可回收。
- 紅線:當 available 持續偏低(如 < 10%~15%)且伴隨系統抖動時,説明內存壓力上升。
- 動作:結合 vmstat 驗證是否在“抖”。
2)vmstat:動態心電圖
vmstat 1 5
解釋:每 1 秒採樣,共 5 次;關注以下列:
- r(可運行隊列):CPU 擁塞信號;與內存關聯看“抖動”時參考。
- free:空閒頁數(頁數×頁大小);波動可見回收節奏。
- si/so:Swap in/out;持續 so>0 表示 <span style="color:red">正在換出</span>,系統已不適。
- bi/bo:塊 IO;頻繁回收會引發 IO 抖動。
- wa:IO wait 走高通常伴隨內存回收/頁回寫。
- 紅線:長時間 so>0 或 wa 高 + available 低 ⇒ 系統在為內存“喘息”。
- 動作:立即定位“增胖”進程(top/ps),必要時先止血(限流/重啓)。
三、進程層定位
3)top:快速鎖定“嫌疑人”
top -o RES
解釋:按 RES(常駐集大小) 排序,快速找到佔用內存最多的進程。
- RES:進程實際佔用的物理頁;一看就懂“誰胖”。
- VIRT:虛擬地址空間總量;大不代表真實佔用高。
- SHR:共享頁。
- 紅線:某進程 RES 持續上漲、系統 available 下滑 ⇒ 高概率內存泄漏或緩存失控。
- 動作:記下 PID → 用 ps/pmap 深挖。
4)ps:導出全局排行榜
ps -e -o pid,ppid,user,cmd,%mem,rss,vsz --sort=-rss | head -20
解釋:按 RSS 排序的 TOP 20 進程。
- %mem:佔系統總內存比例。
- rss:常駐內存(KB)。
- vsz:虛擬內存(KB)。
- 用法:比對多個時間點輸出,確認是否“持續增胖”。
- 動作:對頭部 PID 做 pmap /proc 檢查。
四、對象層解剖
5)pmap:看進程的內存構成
pmap -x <PID> | head -20
解釋:列出各段映射:地址、大小、RSS、髒頁等。
-
關注
- anon 段持續增長 ⇒ 多為 <span style="color:red">堆泄漏/未釋放對象</span>
- file-backed(如 lib / mmap 文件)偏大 ⇒ <span style="color:red">mmap + 文件緩存</span>
- [heap] 增長迅猛 ⇒ 應用層分配(malloc/new)問題
-
動作:
- C/C++:接入 jemalloc/TCMalloc 統計、開啓 ASAN/LSAN;
- JVM:配合
jmap -histo/jcmd GC.class_histogram; - Go:
pprof alloc_space/inuse_space畫像。
6)/proc 輔助位
grep -E 'MemAvailable|Cached|SwapTotal|SwapFree|Dirty|Writeback' /proc/meminfo
解釋:
- MemAvailable:系統可用估算值(關鍵!)
- Cached:頁緩存;
- Dirty/Writeback:髒頁與在回寫中的頁,過高 ⇒ IO 壓力/回收滯後。
- 動作:Dirty 高 + vmstat wa 高 ⇒ 調整髒頁回寫參數或減小突發寫。
五、標準化排障流程(Mermaid 流程圖)
六、核心指標速查表(適配 WordPress 經典編輯器)
| 維度 | 觀察點 | 異常信號 | 結論指向 | 動作建議 |
|---|---|---|---|---|
| 系統 | free: MemAvailable |
<span style="color:red">持續偏低</span> | 全局內存壓力 | 限流/擴容/查進程 |
| 系統 | vmstat: so/wa |
<span style="color:red">so>0、wa 高</span> | 換出/回收致抖 | 查大户、降髒頁 |
| 進程 | top/ps: RSS |
<span style="color:red">持續上漲</span> | 泄漏或緩存失控 | pmap 解剖/採樣 |
| 進程 | pmap: anon/heap |
<span style="color:red">異常放大</span> | 堆/匿名頁問題 | 工具化定位 |
| 內核 | /proc/meminfo: Dirty |
<span style="color:red">高位滯回</span> | 回寫堵塞 | 調整 VM 參數 |
七、可執行的調參參考(謹慎、灰度)
# 觀察頁大小與內存頁統計(輔助換算)
getconf PAGE_SIZE; vmstat -s | head
解釋:確定頁大小(常見 4096B),便於將 vmstat 的“頁數”換算為字節。
# 減緩過度髒頁堆積(按需微調)
sudo sysctl -w vm.dirty_ratio=20
sudo sysctl -w vm.dirty_background_ratio=5
解釋:縮小單次可積累的髒頁比例,避免寫回雪崩;生產需評估 IO 帶寬與業務寫入模型。
# 謹慎啓用/調整 swap(不建議完全關閉;建議小而有)
sudo swapon --show
解釋:小額 swap 可緩衝突發匿名頁;but 持續 so>0 説明已“缺氧”。
八、典型場景打法 🧰
- Java 服務內存高:JVM Xmx 設定過大 + PageCache 與其他服務搶內存 → 觀察
MemAvailable、RSS與GC 日誌,適當 下調 Xmx 並啓用 容器內存限額 與 GC 日誌採樣。 - Nginx/下載服務:高併發大文件 → Cached/Dirty 高、
vmstat wa上升 → 限速、增帶寬、下調 dirty_ratio,或改造為分塊/斷點續傳以降低髒頁峯值。 - C/C++ 泄漏懷疑:
pmap -x見 anon/heap 線性上升 → 接入 jemalloc + mallctl 統計或 ASAN/LSAN;灰度重啓止血,抓現場做火焰圖。
九、結語:把內存問題經營成“可預期的運營成本”
把指標閾值(如 MemAvailable、so、wa、RSS 增速)固化進監控與告警,配合灰度調參與容量規劃,你會發現:內存不是黑魔法,就是賬。用數據説話,團隊就能穩健決策。🙂
一頁要點:
- 看 available,不迷信 free 列;
- vmstat 讀 so/wa 判系統是否“缺氧”;
- top/ps 定位 RSS 大户,pmap 看 anon/heap;
- Dirty/Writeback 揭示回寫與 IO 壓力;
- 小額 swap、合理 dirty 比例、分層限流,組合拳穩態運營。