4.7.6 内存优化实践:大页、缓存回收与参数调优
内存优化实践:大页、缓存回收与参数调优#
内存优化需围绕“减少TLB miss、稳定页缓存回写、避免过量分配与高阶页分配失败”展开。以下内容包含原理草图、可执行命令、参数配置、排错与练习,便于直接落地。
flowchart TD
A[应用内存访问] --> B[页表与TLB]
B --> C[物理页: 4K]
B --> D[大页: 2M/1G]
C --> E[页缓存(Page Cache)]
E --> F[脏页回写]
F --> G[磁盘IO]
C --> H[swap]
1. 大页(HugePages/THP)优化#
适用场景:内存密集型数据库、JVM、缓存类服务。
原则:显式大页可控但占用固定内存;THP易用但可能引起抖动。
查看与判断
# 查看显式大页信息
grep -E "HugePages|Hugepagesize" /proc/meminfo
# 查看THP状态
cat /sys/kernel/mm/transparent_hugepage/enabled
配置显式大页(建议在业务低峰)
# 计算需要的页数(示例:2M页,预留2GB)
# 2GB / 2MB = 1024
echo 1024 > /proc/sys/vm/nr_hugepages
# 确认已分配
grep -E "HugePages_Total|HugePages_Free" /proc/meminfo
关闭THP(常见数据库推荐)
# 临时关闭
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
# 永久关闭(示例:systemd)
cat >/etc/systemd/system/disable-thp.service <<'EOF'
[Unit]
Description=Disable Transparent Huge Pages
After=sysinit.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c "echo never > /sys/kernel/mm/transparent_hugepage/enabled; echo never > /sys/kernel/mm/transparent_hugepage/defrag"
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now disable-thp.service
效果验证
# 观察内存命中与抖动
vmstat 1 5
# 若业务允许,配合压力测试对比p99延迟
排错
- 大页分配失败:内存碎片严重,重启或在低峰预留;适当调高 vm.min_free_kbytes。
- 关闭THP后性能下降:尝试显式大页或仅关闭defrag。
2. 缓存回收与页缓存控制#
关键指标与命令
# 可用内存与缓存占用
free -m
# 回收压力与swap
vmstat 1 5
# 观察脏页、回写
grep -E "Dirty|Writeback|Cached" /proc/meminfo
应急清理页缓存(仅排障,不建议长期频繁)
# 同步脏页后释放缓存
sync
echo 3 > /proc/sys/vm/drop_caches
# 预期:Cached下降,业务IO可能短时波动
脏页回写参数调优(示例:降低回写抖动)
# 临时调整
sysctl -w vm.dirty_background_ratio=5
sysctl -w vm.dirty_ratio=15
sysctl -w vm.dirty_writeback_centisecs=500
sysctl -w vm.dirty_expire_centisecs=3000
# 持久化
cat >>/etc/sysctl.conf <<'EOF'
vm.dirty_background_ratio = 5
vm.dirty_ratio = 15
vm.dirty_writeback_centisecs = 500
vm.dirty_expire_centisecs = 3000
EOF
sysctl -p
效果验证
# 观察回写峰值是否平滑
vmstat 1 10 | awk '{print $1,$2,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15}'
排错
- IO突刺:降低 dirty_ratio 与 dirty_background_ratio。
- 延迟尖刺:缩短 dirty_writeback_centisecs,避免积累过多脏页。
3. 关键内核参数调优#
Swappiness
# 低延迟服务推荐 1~10
sysctl -w vm.swappiness=10
# 持久化
echo "vm.swappiness = 10" >> /etc/sysctl.conf
sysctl -p
VFS缓存压力
# 文件访问频繁场景:降低回收力度
sysctl -w vm.vfs_cache_pressure=50
内存过量分配
# 数据库建议:严格模式
sysctl -w vm.overcommit_memory=2
sysctl -w vm.overcommit_ratio=90
最小保留内存
# 大内存机器适度提高,避免高阶页分配失败
sysctl -w vm.min_free_kbytes=262144
排错
- 内存充足仍触发OOM:检查 overcommit 与 cgroup 限制。
- 高阶页分配失败:提高 min_free_kbytes,或关闭THP。
4. 实践流程(含完整示例)#
目标:在生产前验证参数对延迟与抖动的影响。
# 1) 采集基线
free -m
vmstat 1 5
sar -r 1 5
# 2) 单项调参(示例:降低回写抖动)
sysctl -w vm.dirty_background_ratio=5
sysctl -w vm.dirty_ratio=15
# 3) 压测(示例:fio顺序写)
fio --name=write_test --filename=/data/testfile \
--size=2G --bs=1M --rw=write --direct=0 --iodepth=8 --numjobs=1
# 4) 观察效果
vmstat 1 5
预期效果
- 回写峰值降低,vmstat 中 bo 波动减小;
- 应用 p99 延迟更稳定。
5. 常见问题与处理#
- 内存明明充足仍被OOM Kill
检查vm.overcommit_memory、overcommit_ratio、cgroup限制与大页占用。 - 频繁swap
降低swappiness,排查进程泄漏,必要时扩容。 - IO抖动严重
调低dirty_ratio、dirty_background_ratio,检查存储性能。 - 大页分配失败
低峰预留,增加min_free_kbytes,或重启整理碎片。
6. 练习#
- 大页验证:预留1024个大页,观察
HugePages_Free变化,并写出回滚步骤。 - 脏页回写实验:对比
dirty_ratio=40与dirty_ratio=15的fio写入抖动。 - OOM复现:在测试机中设置
overcommit_memory=2,启动超大内存进程,观察失败日志并分析原因。