前面我们学习了操作系统通过“虚拟内存”技术,不但在功能上突破了物理内存的限制,使程序可以操作大于实际物理内存的空间;更重要的是,隔离了每个进程的安全保护,使每个进程都不受其他程序的干扰。但是,对于系统内存,总是会存在一种场景
当系统的物理内存不够用的时候,就需要将物理内存中的一部分空间释放出来,以供当前运行的程序使用,那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临时保存到Swap空间中,等到那些程序要运行时,再从Swap分区中恢复保存的数据到内存中
正是因为 Linux 上的所有进程都会通过虚拟内存这一层抽象间接与物理内存打交道,而 Swapping 也充分利用了该特性,它能够让应用程序看到操作系统内存充足的假象,然而并不知道它使用的部分虚拟内存其实在磁盘上。希望本文能让了解Linux对swap的使用大概是什么样子。阅读完本文,应该可以帮你解决以下问题:
- swap到底是干嘛的
- swappiness到底是用来调节什么的
- swap分区的优先级(priority)有啥用
1 什么是swap
swap主要是在内存不够用的时候,将部分内存上的数据交换到swap空间上,以便让系统不会因为内存不够用而导致oom或者更致命的情况出现。当内存使用存在压力的时候,开始触发内存回收行为,就可能会使用swap空间。Swap 把这些不常访问的内存先写到磁盘中,然后释放这些内存,给其他更需要的进程使用。再次访问这些内存时,重新从磁盘读入内存就可以了,其原理如下图所示:
Swap就是把一块磁盘空间或者本地文件,当成内存来使用,它包含换出和换入两个过程
- 所谓换出,就是把进程暂时不用的内存数据存储到磁盘中,并释放这些数据占用的内存
- 而换入,则是在进程再次访问这些内存的时候,把它们从磁盘读到内存中来。
我们常见的笔记本电脑的休眠和快速开机的功能,也基于 Swap 。休眠时,把系统的内存存入磁盘,这样等到再次开机时,只要从磁盘中加载内存就可以。这样就省去了很多应用程序的初始化过程,加快了开机速度。
Linux提供两种不同的方法启用Swapping,分别是 Swap 分区(Swap Partition)和 Swap 文件(Swapfile):
- Swap 分区是硬盘上的独立区域,该区域只会用于交换分区,其他的文件不能存储在该区域上,我们可以使用
swapon -s
命令查看当前系统上的交换分区;
book@100ask:~/100ask_imx6ull-qemu/qemu_imx6ull_kernel$ swapon -s
Filename Type Size Used Priority
/dev/sda3 partition 8787964 358400 -2
- Swap 文件是文件系统中的特殊文件,它与文件系统中的其他文件也没有太多的区别;
2 为什么需要swap
- 内存不足:当系统需要的内存超过了可用的物理内存时,内核会将内存中不常使用的内存页交换到磁盘上为当前进程让出内存,保证正在执行的进程的可用性,这个内存回收的过程是强制的直接内存回收(Direct Page Reclaim)。
- 内存闲置:应用程序在启动阶段使用的大量内存在启动后往往都不会使用,通过后台运行的守护进程,我们可以将这部分只使用一次的内存交换到磁盘上为其他内存的申请预留空间。kswapd 是 Linux 负责页面置换(Page replacement)的守护进程,它也是负责交换闲置内存的主要进程,它会在空闲内存低于一定水位时,回收内存页中的空闲内存保证系统中的其他进程可以尽快获得申请的内存
很多人认为当系统内存不足时应该立即触发内存不足(Out of memory、OOM)并杀掉进程,但是 Swapping 其实为系统管理员提供了另外一种选择,利用磁盘的交换空间避免程序被直接退出,以 降低服务质量的代价换取服务的部分可用性 。Linux 中的 Swapping 机制主要是为内存不足和内存闲置两种常见的情况存在的
- Swapping 可以直接将进程中使用相对较少的页面换出内存:当系统需要的内存超过了可用的物理内存时,内核会将内存中不常使用的内存页交换到磁盘上为当前进程让出内存,保证正在执行的进程的可用性;
- Swapping 可以将进程中的闲置页面换出内存:应用程序在启动阶段使用的大量内存在启动后往往都不会使用,通过后台运行的守护进程,我们可以将这部分只使用一次的内存交换到磁盘上为其他内存申请预留空间
3. Swap分区空间什么时候使用
系统在什么情况或条件下才会使用Swap分区的空间呢? 我们应该都知道/proc/sys/vm/swappiness这个文件,是个可以用来调整跟swap相关的参数。这个文件的默认值是60,可以的取值范围是0-100。
这个参数值,控制系统 swap 的使用程度。高数值可优先系统性能,在进程不活跃时主动将其转换出物理内存。低数值可优先互动性并尽量避免将进程转换处物理内存,并降低反应延迟。默认值为 60。注意:这个只是一个权值,不是一个百分比值,涉及到系统内核复杂的算法。
- 这个文件的值用来定义内核使用swap的积极程度。值越高,内核就会越积极的使用swap,值越低就会降低对swap的使用积极性。如果这个值为0,那么内存在free和file-backed使用的页面总量小于高水位标记(high water mark)之前,不会发生交换。
- swappiness=0的时候表示最大限度使用物理内存,然后才是 swap空间,swappiness=100的时候表示积极的使用swap分区,并且把内存上的数据及时的搬运到swap空间里面。
目前默认值为60,也就是说内存在使用到100-60=40%的时候,就开始出现有交换分区的使用。大家知道,内存的速度会比磁盘快很多,这样子会加大系统io,同时造的成大量页的换进换出,严重影响系统的性能,所以我们在操作系统层面,要尽可能使用内存,对该参数进行调整。
4. Swap的含义
在使用多个swap分区或者文件的时候,还有一个优先级的概念(Priority)。在swapon的时候,我们可以使用-p参数指定相关swap空间的优先级,值越大优先级越高,可以指定的数字范围是-1到32767。内核在使用swap空间的时候总是先使用优先级高的空间,后使用优先级低的。当然如果把多个swap空间的优先级设置成一样的,那么两个swap空间将会以轮询方式并行进行使用。如果两个swap放在两个不同的硬盘上,相同的优先级可以起到类似RAID0的效果,增大swap的读写效率。另外,编程时使用mlock()也可以将指定的内存标记为不会换出,具体帮助可以参考man 2 mlock。
5. Swap交换分区对性能的影响
我们知道Linux可以使用文件系统中的一个常规文件或独立分区作为Swap交换空间,相对而言,交换分区要快一些。但是和RAM比较而言,Swap交换分区的性能依然比不上物理内存,目前的服务器上RAM基本上都相当充足,那么是否可以考虑抛弃Swap交换分区,是否不需要保留Swap交换分区呢?
- 当物理内存不足以支撑系统和应用程序(进程)的运作时,这个Swap交换分区可以用作临时存放使用率不高的内存分页,把腾出的内存交给急需的应用程序(进程)使用。有点类似机房的UPS系统,虽然正常情况下不需要使用,但是异常情况下, Swap交换分区还是会发挥其关键作用。
- 即使你的服务器拥有足够多的物理内存,也有一些程序会在它们初始化时残留的极少再用到的内存分页内容转移到 swap 空间,以此让出物理内存空间。对于有发生内存泄漏几率的应用程序(进程),Swap交换分区更是重要,因为谁也不想看到由于物理内存不足导致系统崩溃。
- 现在很多个人用户在使用Linux,有些甚至是PC的虚拟机上跑Linux系统,此时可能常用到休眠(Hibernate),这种情况下也是推荐划分Swap交换分区的。
其实少量使用Swap交换空间是不会影响性能,只有当RAM资源出现瓶颈或者内存泄露,进程异常时导致频繁、大量使用交换分区才会导致严重性能问题。另外使用Swap交换分区频繁,还会引起kswapd0进程(虚拟内存管理中, 负责换页的)耗用大量CPU资源,导致CPU飙升。
6. 总结
关于swap的使用,针对不同负载状态的系统是不一样的。有时我们希望swap大一些,可以在内存不够用的时候不至于触发oom-killer导致某些关键进程被杀掉,比如数据库业务。也有时候我们希望不要swap,因为当大量进程爆发增长导致内存爆掉之后,会因为swap导致IO跑死,整个系统都卡住,无法登录,无法处理。这时候我们就希望不要swap,即使出现oom-killer也造成不了太大影响,但是不能允许服务器因为IO卡死像多米诺骨牌一样全部死机,而且无法登陆。跑cpu运算的无状态的apache就是类似这样的进程池架构的程序。