3、操作系统层面的内存优化:虚拟内存与交换空间,内存回收机制,大页内存配置
聊到内存优化,很多人第一反应就是加内存条。但说实话,在系统层面把现有内存榨干,才是真本事。我这些年调过不少服务器,发现操作系统层面的配置,往往比换硬件更立竿见影。今天咱们就聊聊虚拟内存、交换空间、内存回收和大页内存这几个硬骨头。
3.1 虚拟内存与交换空间:别让Swap成为性能杀手
虚拟内存这个概念,说白了就是给每个进程画了个大饼——让它们以为自己独占整个地址空间。实际上,物理内存不够用的时候,操作系统会把不常用的内存页挪到磁盘上,这就是交换空间(Swap)干的事。
嗯,这里要注意:Swap不是万能的。我曾经接手过一个Java应用,内存占用飙到8GB,Swap用了6GB,结果GC停顿时间从50ms直接跳到3秒。为什么?因为磁盘IO比内存慢几个数量级。你想想看,GC线程要扫描对象,结果对象在磁盘上,那不得卡死?
配置Swap其实很简单,但要注意分区位置。我个人习惯把Swap放在SSD上,而不是机械盘。命令如下:
# 创建Swap文件(4GB)
dd if=/dev/zero of=/swapfile bs=1M count=4096
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
# 查看Swap使用情况
swapon --show
free -h
还有一个关键参数:swappiness。它控制内核使用Swap的倾向性,范围0~100。默认是60,但我建议调低到10~30。为什么?因为Linux内核太积极了,明明还有空闲内存,它就开始换出页面,反而影响性能。
# 临时调整
sysctl vm.swappiness=10
# 永久生效
echo "vm.swappiness=10" >> /etc/sysctl.conf
3.2 内存回收机制:内核的"垃圾清理工"
操作系统内核其实有个后台线程,叫kswapd,专门负责内存回收。它会在内存压力达到一定阈值时启动,把不活跃的页面换出去。但这里有个坑:如果内存分配速度超过回收速度,系统就会直接触发OOM Killer,把进程杀掉。
我在项目中遇到过这种情况:一个Redis实例突然被OOM Killer干掉,排查了半天才发现是内存碎片太多,加上回收不及时。后来我调整了vm.min_free_kbytes参数,预留了一些内存给紧急分配用,问题就解决了。
vm.min_free_kbytes:保留的最小空闲内存,防止内存分配失败vm.vfs_cache_pressure:控制VFS缓存回收力度,默认100,调低可减少inode/dentry回收vm.dirty_ratio&vm.dirty_background_ratio:控制脏页刷盘时机
举个例子,如果服务器上跑着大量文件操作,我建议调低vm.dirty_ratio,避免脏页积压太多导致IO卡顿:
# 脏页占内存比例超过10%时开始后台刷盘
sysctl vm.dirty_background_ratio=10
# 脏页占内存比例超过20%时阻塞写入
sysctl vm.dirty_ratio=20
你想想看,如果脏页比例设得太大,突然大量写入时,系统要一次性刷盘,那IO延迟直接爆炸。所以,宁可频繁刷,也别攒着一次性刷。
3.3 大页内存配置:给数据库和虚拟化开"绿色通道"
大页内存(HugePages)是个好东西,尤其对数据库、Java应用和虚拟化场景。为什么?因为TLB(页表缓存)是有限的,默认4KB的小页会导致TLB频繁失效。换成2MB甚至1GB的大页,TLB命中率直线上升。
我记得有一次帮客户调优Oracle数据库,启用大页后,CPU使用率直接降了15%。说白了,就是减少了页表遍历的开销。
- 检查当前大页支持:
grep Huge /proc/meminfo - 设置大页数量:
echo 1024 > /proc/sys/vm/nr_hugepages - 挂载hugetlbfs:
mount -t hugetlbfs hugetlbfs /dev/hugepages - 应用配置(如Java):
-XX:+UseLargePages -XX:LargePageSizeInBytes=2m
但要注意,大页内存是预分配的,不能动态调整。我曾经犯过一个错:给一个虚拟机分配了太多大页,结果其他进程内存不够用,直接OOM。所以,大页内存适合给明确知道内存需求的场景,比如数据库缓冲池。
另外,Linux 2.6.38之后引入了透明大页(THP),它会自动把小页合并成大页。听起来很美,但实际坑很多。我在项目中遇到过THP导致的内存碎片和延迟抖动,尤其是对实时性要求高的应用。建议关掉:
# 关闭透明大页
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
知识体系总览
下面这张图,是我梳理的操作系统内存优化核心逻辑。你可以看到,虚拟内存、交换空间、内存回收和大页配置,其实都围绕着同一个目标:让物理内存用得更高效,减少不必要的磁盘IO和CPU开销。
最后说一句,内存优化不是一锤子买卖。我每次调完参数,都会用vmstat、sar和/proc/meminfo持续观察几天,确认没有副作用。毕竟,系统优化就像调琴弦,松了没效果,紧了容易断。
- Swap:调低swappiness,放在SSD上
- 回收:调整dirty_ratio和min_free_kbytes
- 大页:手动分配HugePages,关掉THP