記憶體是系統效能的關鍵。本文深入剖析 32/64 位元架構下的虛擬記憶體映射、頁表分級、TLB 快取、頁面置換演算法、Swap 機制、OOM Killer、記憶體區域劃分,並提供實戰調優參數與監控指標。
# x86_64 4 級頁表(4KB 頁)
CR3 (PML4) → PML4 Entry → PDP (Page Directory Pointer) → PD (Page Directory) → PT (Page Table) → Physical Page
# 32 位元 PAE 模式 3 級頁表
CR3 → PDP → PD → PT → Page
vm.swappiness=10(資料庫/低延遲服務),=60(一般應用)oom_score = 基礎分數 + 調整因子
# 基礎分數:佔用記憶體比例
# 調整:oom_score_adj (-1000 ~ 1000,-1000 永不殺死)
# 關鍵進程保護:echo -1000 > /proc//oom_score_adj
cat /proc//oom_score
cat /proc//oom_score_adj
# 永久配置:/etc/sysctl.d/99-oom.conf
vm.oom_kill_allocating_task = 0
vm.panic_on_oom = 0
cat /proc/zoneinfo 查看各區域水位線slabtop 觀察快取使用狀況# /etc/sysctl.d/99-memory.conf
# Swap 激進度
vm.swappiness = 10
# Dirty page 回寫控制(避免大量髒頁一次寫入造成延遲尖峰)
vm.dirty_ratio = 15 # 髒頁佔比上限觸發同步寫入
vm.dirty_background_ratio = 5 # 背景回寫啟動閾值
vm.dirty_expire_centisecs = 3000 # 髒頁最老壽命 30 秒
vm.dirty_writeback_centisecs = 500 # 背景回寫間隔 5 秒
# 記憶體過量分配
vm.overcommit_memory = 1 # 1=總是允許(適合 Redis/資料庫),0=啟發式,2=嚴格
vm.overcommit_ratio = 50 # overcommit_memory=2 時的實體+swap 比例
# HugePages(資料庫/大記憶體應用)
vm.nr_hugepages = 1024 # 2MB 頁 × 1024 = 2GB
# 需在 /etc/security/limits.conf 給用戶 memlock 權限
# 避免 OOM 殺死關鍵進程
vm.oom_kill_allocating_task = 0
vm.panic_on_oom = 0
| 工具 | 用途 | 關鍵指標 |
|---|---|---|
| free -h | 整體記憶體使用 | available(真正可用)、buff/cache |
| vmstat 1 | 虛擬記憶體統計 | si/so(swap in/out)、bi/bo(block IO)、cs(context switch) |
| pidstat -r 1 | 進程記憶體統計 | RSS、VSZ、MinFLT、MajFLT(缺頁中斷) |
| smem | PSS/USS 精確記憶體 | 共享記憶體比例分攤 |
| pmap -x PID | 進程記憶體映射詳情 | 各段權限、RSS、Dirty |
| /proc/meminfo | 核心記憶體詳細資訊 | SReclaimable、SUnreclaim、PageTables、KernelStack |
| numastat | NUMA 節點記憶體分布 | 跨節點存取比例 |
numactl --hardware 查看拓撲numactl --cpunodebind=0 --membind=0 ./appvm.zone_reclaim_mode = 1(嘗試本地回收而非跨節點分配)# Docker
docker run -m 2g --memory-swap 4g --oom-kill-disable=false ...
# K8s
resources:
limits:
memory: "2Gi"
requests:
memory: "1Gi"
# 容器內 /sys/fs/cgroup/memory/memory.limit_in_bytes 反映限制
vm.swappiness=10、dirty_ratio 適中oom_score_adj=-1000Major Faults、Swap IO、OOM Kill 事件