概述

本文讨论的 swap基于Linux4.4内核代码 。Linux内存管理是一套非常复杂的系统,而swap只是其中一个很小的处理逻辑。主要是:swap、swappiness及kswapd原理,swap分区优先级的妙用。

解决以下问题:

1、 swap到底是干嘛的?

2、 什么是内存水位标记?

3、 swap分区的优先级(prIOrity)有啥用?


1、什么是SWAP,到底是干嘛的?

我们一般所说的swap,指的是一个交换分区或文件。在Linux上可以使用swapon -s命令查看当前系统上正在使用的交换空间有哪些,以及相关信息:

$ swapon -s filename Type Size Used Priority /dev/dm-4 partition 33554428 0 -1

从功能上讲,交换分区主要是在内存不够用的时候,将部分内存上的数据交换到swap空间上,以便让系统不会因内存不够用而导致oom或者更致命的情况出现。

所以,当内存使用存在压力,开始触发内存回收的行为时,就可能会使用swap空间。

内核对swap的使用实际上是跟内存回收行为紧密结合的。那么关于内存回收和swap的关系,我们需要思考以下几个问题:

  1. 为什么要进行内存回收?
  2. 哪些内存可能会被回收呢?
  3. 回收的过程中什么时候会进行交换呢?
  4. 具体怎么交换?

下面我们就从这些问题出发,一个一个进行分析。


为什么要进行内存回收?

根据这个enum可以看到,内存回收主要需要进行扫描的链表有如下4个:

就是说,内存回收操作主要针对的就是内存中的文件页(file cache)和匿名页。

关于活跃(active)还是不活跃(inactive)的判断内核会使用lru算法进行处理并进行标记,我们这里不详细解释这个过程。


整个扫描的过程分几个循环:

  1. 首先扫描每个zone上的cgroup组;
  2. 然后再以cgroup的内存为单元进行page链表的扫描;
  3. 内核会先扫描anon的active链表,将不频繁的放进inactive链表中,然后扫描inactive链表,将里面活跃的移回active中;

linux里面swap指令是什么(LinuxSWAP深度解读)(1)

4.进行swap的时候,先对inactive的页进行换出;

5.如果是file的文件映射page页,则判断其是否为脏数据,如果是脏数据就写回,不是脏数据可以直接释放。

这样看来, 内存回收这个行为会对两种内存的使用进行回收:

因为针对filebased的内存,没必要进行交换,其数据原本就在硬盘上,回收这部分内存只要在有脏数据时写回,并清空内存就可以了,以后有需要再从对应的文件读回来。

内存对匿名页和文件缓存一共用了 四条链表 进行组织,回收过程主要是针对这四条链表进行扫描和操作。


2 、什么是内存水位标记?(watermark)

那么如何描述内存使用的压力呢?

Linux内核使用水位标记(watermark)的概念来描述这个压力情况。

Linux为内存的使用设置了三种内存水位标记:high、low、min。他们 所标记的含义分别为:

内存回收行为就是基于剩余内存的水位标记进行决策的:

当系统剩余内存低于watermark[low]的时候,内核的kswapd开始起作用,进行内存回收。直到剩余内存达到watermark[high]的时候停止。

如果内存消耗导致剩余内存达到了或超过了watermark[min]时,就会触发直接回收(direct reclaim)。

明白了水位标记的概念之后,zonefile zonefree <= high_wmark_pages(zone)这个公式就能理解了。

这里的zonefile相当于内存中文件映射的总量,zonefree相当于剩余内存的总量。

内核一般认为,如果zonefile还有的话,就可以尽量通过清空文件缓存获得部分内存,而不必只使用swap方式对anon的内存进行交换。

整个判断的概念是说,在全局回收的状态下(有global_reclaim(sc)标记),如果当前的文件映射内存总量 剩余内存总量的值评估小于等于watermark[high]标记的时候,就可以进行直接swap了。

这样是为了防止进入cache陷阱,具体描述可以见代码注释。

这个判断对系统的影响是, swappiness设置为0时,有剩余内存的情况下也可能发生交换。


swap的相关操纵命令

可以使用mkswap将一个分区或者文件创建成swap空间。swapon可以查看当前的swap空间和启用一个swap分区或者文件。swapoff可以关闭swap空间。

我们使用一个文件的例子来演示一下整个操作过程:

制作swap文件:

linux里面swap指令是什么(LinuxSWAP深度解读)(2)

启用swap文件:

linux里面swap指令是什么(LinuxSWAP深度解读)(3)

关闭swap空间:

linux里面swap指令是什么(LinuxSWAP深度解读)(4)


3、swap分区的优先级(priority)有啥用?

在使用多个swap分区或者文件的时候,还有一个优先级的概念(Priority)。

在swapon的时候,我们可以使用-p参数指定相关swap空间的优先级, 值越大优先级越高 ,可以指定的数字范围是-1到32767。

内核在使用swap空间的时候总是先使用优先级高的空间,后使用优先级低的。

当然如果把多个swap空间的优先级设置成一样的,那么两个swap空间将会以轮询方式并行进行使用。

如果两个swap放在两个不同的硬盘上,相同的优先级可以起到类似RAID0的效果,增大swap的读写效率。

另外,编程时使用mlock()也可以将指定的内存标记为不会换出,具体帮助可以参考man 2 mlock。


总结

关于swap的使用建议,针对不同负载状态的系统是不一样的。有时我们希望swap大一些,可以在内存不够用的时候不至于触发oom-killer导致某些关键进程被杀掉,比如数据库业务。

也有时候我们希望不要swap,因为当大量进程爆发增长导致内存爆掉之后,会因为swap导致IO跑死,整个系统都卡住,无法登录,无法处理。

这时候我们就希望不要swap,即使出现oom-killer也造成不了太大影响,但是不能允许服务器因为IO卡死像多米诺骨牌一样全部死机,而且无法登陆。跑cpu运算的无状态的apache就是类似这样的进程池架构的程序。


觉得有用的关注下哦~

linux里面swap指令是什么(LinuxSWAP深度解读)(5)

,