一、内存管理体系概览

Linux内核的内存管理子系统是操作系统中最复杂且最关键的组成部分之一。它负责着虚拟内存到物理内存的映射管理、页面分配与回收、进程间隔离与共享、以及高压场景下的稳定性保障。本文将从硬件层面的TLB和MMU出发,深入分析五级页表结构、Buddy分配器、Slab缓存、反向映射、KSM页面合并、LRU回收机制与OOM Killer,最后结合真实生产环境的性能调优案例,帮助读者建立完整的内存管理知识框架。

二、实现原理

Linux内存管理体系的核心映射关系是:虚拟地址→虚拟页号→物理页帧号。这一转换由MMU完成,通过五级页表(x86_64下为4级,但架构上保留五级)实现平滑迁移。TLB(Translation Lookaside Buffer)作为MMU的页表缓存,关键巴维内存访问能效提升并表现。

Buddy分配器管理物理页面: 维护10个的free_area数组,每个free_area管理2^(0-10)元的碎片。通过拆分与合并机制最大限度减少外部碎片。Br子系统(如ext4 xfs)联合vm子系统实现高效的物理分配和流控。

# cat /proc/buddyinfo → 
Node 0, zone DMA		1 1 1 2 2 3 2 2 1 1
Node 0, zone DMA32	  150 129 72 41 18 9 4 2 1 1
Node 0, zone Normal	  2780 1590 821 647 316 156 82 44 18 9 1

(从/proc/zoneinfo可看到详细的永久和泄露口Sp信息)

Slab/Slob/Slub三大分责器对内核对象的高效分配与回收。通过kmem_cache管理各类对象,无需再自行填瓦,基本原理是预划一定量的Head预划对象,直接付内存使用。Buddy分配器由Slab请求时,Slab将会向Buddy系统申请一个或多个页面,并检查到Slab中,块后回收到原先Buddy。

# 查看Slab内存使用情况
cat /proc/slabinfo

# 用free查看内存状态
free -m
#  total used free shared buff/cache available
Mem:  16384 8192 2048  512   5632  10240

# 查看HugePages配置
/proc/sys/vm/nr_hugepages
/proc/sys/vm/nr_overcommit_hugepages

Reverse Mapping(反向映射):addr页面的回收入础。由于多个进程可能共享同一个物理页面,内存回收时需要追溯所有引用该页面的VMA和PTE。Linux 2.6引入rmap,量有将进程的虚拟内存映射到其anim对象数组,后继则对页表项。

KSM(Kernel Same-page Merging):用于虚拟化服务器的内存超分配(overcommit)。KSM将相同的页面合并为一份物理内存,并与COW与COW对管理合并管理。

三、开发实践

1. THP(Transparent Huge Page):如果如AT、Redis、Java JVM、优化的应用在长时间全郊的运行中需要连续的物理内存,开启可减少TLB miss。

# 显式开启THP
echo always > /sys/kernel/mm/transparent_hugepage/enabled
echo defer > /sys/kernel/mm/transparent_hugepage/defrag

(了解的内核无份区分TLB的头尾区间)

2. KSM配置优化虚拟化服务器:在虚拟化地坐中提升内存利用率,但需评估CPU开销。

# 开启KSM
echo 1 > /sys/kernel/mm/ksm/run
echo 1000 > /sys/kernel/mm/ksm/pages_to_scan  # 每轮扫描页数
echo 500 > /sys/kernel/mm/ksm/sleep_millisecs  # 扫描间隔的秒数

3. 控制内存超分:sysctl vm.overcommit_memory,适用于将过历发现内存不足的情况,在生产环境中都是开启的。

# overcommit 策略:):
# 0:内核自动判断(默认)
# 1:永远允许有超分配(适用于malloc大块别)
# 2:不允许超分配
sysctl -w vm.overcommit_memory=1
sysctl -w vm.overcommit_ratio=80

4. 调整swappiness:控制内存回收是否偏向swap还是文件页面回收。对于数据库生产环境,建议降至较低值(10-30)。

sysctl -w vm.swappiness=10

# 来自Red Hat的建议:
# PostgreSQL/MySQL 数据库服务器、Redis 缓存:1-10
# 文件服务器/Web 服务器,清单 :30-60
# KVM/QEMU 虚拟化服务器,强烈建议关闭swap(vm.swappiness=1)

四、OOM Killer与实战

Linux内核的OOM(Out of Memory) Killer是内存不足时的最垠底线。这个机制在物理内存和swap都用尽之后会根据一定的分数算法选择进程杀掉,以秉持系统的运行。

规避OOM Kill的办法:

  1. 通过cgroups限制组当进程的内存使用上限
  2. 调整oom_score和om_adj变量,低优先级的进程最先被杀
  3. 开启系统约末panic_on_oom=2,当内存不足时用进程的系统panic决定重启
# 调整目标的OOM优先级(-1000 到 1000)
echo -1000 > /proc/51668/oom_score_adj

# 开启吞末系统约panic
sysctl -w vm.panic_on_oom=2

# OOM内核日志
dmesg | grep -i "out of memory"

痛点与方法:

1.Buddy分配器的外部碎片问题:长时间运行后物理内存可能不足,导致分配失败。预防措施:

#忩服务器配置起始末尾开启的时候利用@Compaction敢复碎片。
echo 1 > /proc/sys/vm/compact_memory

2.KSM的内存扫描开销:实际无需扫描无际具及都是CPU,却导致CPU使用率七升。

3.OOM Kill引发的服务断块:至间时间可能服务中断1-2s 或到1min。

五、总结

内存管理是Linux内核中最复杂、最关键的子系统之一。理解其原理对于生产环境优化至关重要。应用程序应根据业务特点选择适合的优化策略如TPH,KSM,平衡内存利用率与CPU开销,并对OOM处理有清晰的备案。

参考资料:

  • Professional Linux Kernel Architecture,Wolfgang Mauerer
  • Linux Kernel Development:Robert Love
  • Understanding the Linux Virtual Memory Manager,https://www.kernel.org/doc/html/latest/mm/index.html
点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部