关键不是“一刀切改参数”,而是根据workload类型、NUMA拓扑和应用特征,有针对性地控制内存来源、分配方式与回收时机,包括NUMA绑定、调整vm.swappiness、cgroups v2内存隔离及减少小对象高频分配。

看清楚当前内存分配是否跨 NUMA 节点
NUMA 架构下,进程在 CPU0 上运行,却从 node1 分配内存,会显著拖慢访问速度。先确认系统是否启用了 NUMA:cat /proc/cpuinfo | grep "numa" 或 numactl --hardware
如果显示多个 node,再查当前进程的内存分布:numastat -p <PID> —— 关注“Numa_Hit”和“Numa_Remote”列;Remote 高说明频繁跨节点访问。
- 对数据库、Redis 等内存密集型服务,启动时加 numactl --cpunodebind=0 --membind=0 ./your_app,强制绑定到同一节点
- 若需均衡负载,改用 numactl --interleave=all,但仅适用于读写均匀、无局部性特征的应用
- 避免全局修改 /sys/devices/system/node/nodeX/numa_policy,容易引发意外调度行为
控制 page cache 与 swap 的权衡边界
内核默认倾向保留大量 page cache(提升文件读写),但当匿名内存(如 Java 堆)增长快时,可能因过度 swap 影响响应延迟。核心参数是 vm.swappiness(0–100),它不决定“是否 swap”,而是影响“回收时优先踢出 cache 还是换出匿名页”的倾向:
- 值高(如 60+):cache 回收更保守,匿名页更容易进 swap → 适合桌面或缓存型服务
- 值低(如 1–10):更愿意丢弃干净 cache 页,减少 swap 活动 → 适合数据库、实时服务
- 不建议设为 0:完全禁用 swap 会使 OOM killer 更早触发,反而降低容错性
按业务粒度隔离内存使用(cgroups v2)
单靠全局参数无法解决“某个容器吃光内存导致其他服务抖动”的问题。cgroups v2 提供了更精细的内存控制能力。例如限制某服务最多使用 4GB 内存,并启用 soft limit 避免硬杀:
- mkdir -p /sys/fs/cgroup/db-service
- echo 4G > /sys/fs/cgroup/db-service/memory.max
- echo 3.5G > /sys/fs/cgroup/db-service/memory.low(内核会优先保护这部分内存不被回收)
- 把进程加入:echo <PID> > /sys/fs/cgroup/db-service/cgroup.procs
避免小对象高频分配带来的内核开销
频繁调用 malloc/free(尤其 这不是 sysctl 能调的,而是应用层优化方向:- 对固定大小小对象(如网络包头、日志结构体),在用户态实现简易内存池,预分配一批块并链表管理
- 用 slabtop 查看哪些 kmem_cache 占用高(如 dentry、inode_cache),再结合业务判断是否异常
- 确认是否启用了 SLUB(现代发行版默认),它比老式 SLAB 更轻量、更适合多核



















