一, Swap 原理
前面提到, Swap 说白了就是把一块磁盘空间或者一个本地文件(以下讲解以磁盘为例), 当成内存来使用. 它包括换出和换入两个过程
1, 所谓换出
就是把进程暂时不用的内存数据存储到磁盘中, 并释放这些数据占用的内存.
2, 换入
则是在进程再次访问这些内存的时候, 把它们从磁盘读到内存中来
所以你看, Swap 其实是把系统的可用内存变大了. 这样, 即使服务器的内存不足, 也可以运行大内存的应用程序
3, 应用场景
即是内存不足时, 有些程序也并不像被 OOM 杀死, 二十希望能缓一段时间, 等待人工介入, 或者等系统自动释放其他程序的内存, 再分配给它(可以给运维人员处理故障一个缓冲的时间)
常见的笔记本电脑休眠和快速开机的功能, 也基于 Swap , 休眠时, 把系统内存存入磁盘, 这样等到再次开机时, 只要从磁盘中加载内存就可以, 这样就省去了很多应用程序的初始化过程, 加快了开机速度
二, 那么 Linux 到底在什么时候需要回收内存呢?
1, 直接内存回收
有新的大块内存分配请求, 但是剩余内存不足, 这个时候系统就需要回收一部分内存(比如前面提到的缓存), 进而尽可能地满足新内存请求, 这个过程被称为直接内存回收
2,kswapd0(定期回收内存)
1, 剩余内存页<最小阈值
- root@openstack:~# free -h
- total used free shared buff/cache available
- Mem: 4.9G 114M 4.0G 992K 770M 4.5G
- Swap: 3.9G 0B 3.9G
- root@openstack:~# cat /proc/sys/vm/min_free_kbytes
- 67584
说明进程可用内存都耗尽了, 只有内核才可以分配内存
2, 页最小阈值<剩余内存页<页低阈值
内存压力比较大, 剩余内存不多了, 这是 kswapd0 会执行内存回收, 直接剩余内存大于高阈值为止
3, 页低阈值<剩余内存<页高阈值
说明有一定压力, 但还可以满足新内存请求
4, 剩余内存>页高阈值
说明剩余内存比较多, 没有内存压力
- watch -d grep -A 15 'Normal' /proc/zoneinfo
- Every 2.0s: grep -A 15 Normal /proc/zoneinfo openstack: Wed Feb 6 08:45:01 2019
- Node 0, zone Normal
- pages free 146583
- min 4986
- low 6232
- high 7478
- spanned 399872
- present 399872
- managed 373102
- protection: (0, 0, 0, 0, 0)
- nr_free_pages 146583
- nr_zone_inactive_anon 35
- nr_zone_active_anon 11422
- nr_zone_inactive_file 64699
- nr_zone_active_file 120441
- nr_zone_unevictable 1352
- nr_zone_write_pending 0
三, 为什么剩余内存很多的情况下, 也会发生 Swap 呢?
这正是处理器的 NUMA (Non-Uniform Memory Access)架构导致的.
在 NUMA 架构下, 多个处理器被划分到不同 Node 上, 且每个 Node 都拥有自己的本地内存空间.
而通一个 Node 内部的内存空间实际上可以进一步分为不同的内存域. 比如直接内存访问区域, 普通内存区, 伪内存去等如下图所示
1, 通过 numactl 查询 node 的分布情况
- root@openstack:~# numactl --hardware
- available: 1 nodes (0)
- node 0 cpus: 0 1
- node 0 size: 4976 MB
- node 0 free: 4088 MB
- node distances:
- node 0
- 0: 10
1,NUMA 和 swap 什么关系?
1, 三个内存阈值 (页最小阈值, 页低阈值和页高阈值) 查询
- cat /proc/zoneinfo
- Node 0, zone Normal
- pages free 146583
- min 4986
- low 6232
- high 7478
- spanned 399872
- present 399872
- managed 373102
- protection: (0, 0, 0, 0, 0)
- nr_free_pages 146583
- nr_zone_inactive_anon 35
- nr_zone_active_anon 11422
- nr_zone_inactive_file 64699
- nr_zone_active_file 120441
- nr_zone_unevictable 1352
- nr_zone_write_pending 0
1,pages 处的 min,low,high, 就是上面提到的三个内存阈值, 而 free 是剩余内存页数, 它跟后面的 nr_free_pages 相同
2,nr_zone_active_anon 和 nr_zone_inactive_anon, 分别是活跃和非活跃的一名页数
3,nr_zone_active_file 和 nr_zone_inactive_anon, 分别是活跃和非活跃的文件页数
从这个输出结果可以发现, 剩余内存远大于高阈值, 所以此时的不会回收内存
2,Node 寻找空闲内存还是本地内存中回收内存?
- root@openstack:~# cat /proc/sys/vm/zone_reclaim_mode
- 0
默认的 0, 也就是刚刚提到的模式, 表示既可以从其他 Node 寻找空闲内存, 也可以从本地回收内存
1,1,2,4 都表示只回收本地内存,
2,2 表示可以回写脏数据回收内存
3,4 表示可以用方式回收
3, 到底该先回收哪一种呢?
1, 对文件页的回收
当然就是直接回收缓存, 或者把脏页写回磁盘后再回收
2, 而对匿名页的回收
其实就是通过 Swap 机制, 把它们写入磁盘后再释放内存
- root@openstack:~# cat /proc/sys/vm/swappiness
- 60
swappiness 的范围是 0-100, 数值越大, 越积极使用 Swap, 更倾向于回收匿名页;
也就是更倾向于回收匿名页; 数值越小, 越消极使用 Swap, 也就是更倾向于回收文件页
虽然 swappiness 的范围是 0-100, 不过要注意, 这并不是内存的百分比, 而是 Swap 调整积极程度的权重
即使你把它设置成 0, 当剩余内存 + 文件页小于也高阈值时, 还是会发生 Swap
Linux 性能优化实战: 系统的 swap 变高(08)
来源: http://www.bubuko.com/infodetail-2946097.html