下面是 Day 3:内存管理与Swap机制 学习内容,包含讲解、示例、练习与 FAQ,方便循序渐进学习。
Day 3:Linux 内存管理与 Swap 机制
目标:掌握 Linux 内存管理基本原理、Swap 工作机制,并能够排查 OOM(Out of Memory)问题。
3.1 内存管理概述
Linux 内存管理的核心任务是 高效管理有限的物理内存,同时为用户空间程序提供统一、隔离的虚拟内存空间。
3.1.1 虚拟地址空间布局
Linux 将 虚拟内存地址空间 分为两部分:
bash
用户空间:0x00000000 - 0xBFFFFFFF # 应用程序使用
内核空间:0xC0000000 - 0xFFFFFFFF # 内核保留
32 位系统通常是 3G 用户态 + 1G 内核态 的分布。 在 64 位系统中,用户空间和内核空间分布更大,但原理相同。
示意图:虚拟地址空间布局
sql
+----------------------+ 0xFFFFFFFF
| 内核空间 (Kernel) |
| 内核代码 / 驱动 / |
| 内核缓存 / 内核栈 |
+----------------------+ 0xC0000000
| |
| 用户空间 (User) |
| 程序代码、堆、栈等 |
| |
+----------------------+ 0x00000000
3.1.2 分页机制与页表 (Page Table)
Linux 使用 分页机制 (Paging) 将虚拟地址映射到物理内存。
- 页(Page) :内存管理的最小单位,通常为 4KB。
- 页表 (Page Table):记录虚拟页与物理页的映射关系。
示意图:分页映射
lua
虚拟地址空间
+----------+ +----------+
| Page #1 | ---> | Frame #7 |
+----------+ +----------+
| Page #2 | ---> | Frame #2 |
+----------+ +----------+
| Page #3 | ---> | Frame #5 |
+----------+ +----------+
优势:
- 提供隔离,每个进程有独立的虚拟空间。
- 解决物理内存不足问题,支持 Swap。
3.1.3 伙伴系统 (Buddy System)
Linux 使用 伙伴系统 进行物理内存页的分配。
- 将内存按 2 的幂次方分块(4KB、8KB、16KB...)。
- 当需要分配时,找到最接近的块;释放时,尝试与相邻空闲块合并。
优点:
- 减少内存碎片。
- 高效分配和回收。
3.1.4 SLAB / SLUB 分配器
针对小内存对象(如 task_struct
),Linux 引入 SLAB/SLUB 分配器来提高效率。
特性 | SLAB | SLUB |
---|---|---|
结构复杂度 | 高 | 简单 |
适合场景 | 大型系统 | 通用系统 |
默认内核选择 | 早期内核 | 新版本默认使用 |
类比 : 伙伴系统像 仓库管理整箱货物 ,SLAB/SLUB 则像 便利店拆分小包装,避免浪费。
3.2 Swap 与 OOM 机制
3.2.1 什么是 Swap
当物理内存不足时,Linux 会将 不活跃的内存页 移到 磁盘上的 Swap 空间,释放物理内存。
- 优点:防止物理内存不足导致程序崩溃。
- 缺点:Swap 在磁盘上,速度远低于物理内存 → 会明显拖慢性能。
3.2.2 Swap 触发机制
内核根据 页面回收算法 判断是否触发 Swap。
关键参数:vm.swappiness
-
范围:
0 ~ 100
-
含义:倾向于 Swap 的强度。
vm.swappiness = 0
→ 尽量避免 Swap。vm.swappiness = 100
→ 积极使用 Swap。
查看当前值:
bash
cat /proc/sys/vm/swappiness
临时修改:
bash
sudo sysctl -w vm.swappiness=10
永久修改:
bash
echo "vm.swappiness = 10" | sudo tee -a /etc/sysctl.conf
3.2.3 kswapd 工作流程
-
kswapd 是内核中的后台线程,负责回收页面。
-
当内存紧张时,kswapd 会:
- 扫描 LRU(最近最少使用)链表。
- 将不活跃的页面写入 Swap。
- 回收释放出来的物理页。
3.2.4 OOM(Out of Memory)
如果内存和 Swap 都耗尽,内核会触发 OOM Killer,选择一个进程强制杀死。
影响 OOM 的参数
-
Overcommit 策略
/proc/sys/vm/overcommit_memory
0
:启发式策略(默认)1
:允许分配超出物理内存+Swap2
:严格限制分配
-
oom_score
/proc/<pid>/oom_score
数值越高,被杀掉的概率越大。
3.2.5 OOM 日志示例
当 OOM 发生时,dmesg
会输出类似日志:
yaml
Out of memory: Kill process 2345 (java) score 920 or sacrifice child
Killed process 2345 (java), UID 1000, total-vm:204800kB, anon-rss:102400kB
3.3 内存管理工具
工具 | 用途 | 示例命令 |
---|---|---|
free |
总体内存和 Swap 使用情况 | free -m |
sar -r |
内存趋势监控 | sar -r 1 10 |
smem |
进程级内存分布 | smem -r |
pmap |
查看进程内存段 | pmap <pid> |
vmstat |
内存、CPU、IO 综合监控 | vmstat 1 5 |
Day 3 练习
练习 1:调整 swappiness
-
查看当前
vm.swappiness
值:bashcat /proc/sys/vm/swappiness
-
设置为 10,并观察 Swap 使用变化:
bashsudo sysctl -w vm.swappiness=10
-
启动内存压力工具,如
stress
,观察free -m
输出。
练习 2:模拟 OOM
-
使用
stress
创建内存压力:bashsudo apt install stress -y stress --vm 4 --vm-bytes 512M --timeout 60s
-
查看
dmesg
,分析 OOM 日志。
练习 3:pmap 分析进程内存布局
-
查找某个进程 PID:
bashps aux | grep firefox
-
使用
pmap
查看内存段:bashpmap <pid>
FAQ
-
Q:Swap 是不是越大越好? A:不是。Swap 过大只会让系统更慢,通常建议 Swap = 物理内存的 1-2 倍。
-
Q:如何判断 OOM 是谁导致的? A:通过
dmesg
或/var/log/messages
中的 OOM Killer 日志,查看被杀掉的进程和oom_score
。 -
Q:swappiness 设置多少合适? A:桌面系统可设为 10-20;服务器可设为 0-5。
-
Q:Swap 对 SSD 是否有损伤? A:Swap 会产生大量写入,对 SSD 有一定损耗,但现代 SSD 一般足以承受。
最终学习目标
完成本日课程后,应该能够:
- 熟练解释 Linux 内存管理原理。
- 通过
free
、vmstat
、pmap
等工具分析内存问题。 - 调整 Swap 策略,理解 kswapd 和 OOM 的工作机制。
- 定位和解决常见内存不足问题。