reclaim 开源技术分享:Linux 内核参数 swappiness细解

本文主要分析一个swappiness的源代码(基于内核版本v4.14-13151-g5a787756b809),仅供个人意见。如有不足,请互相沟通。
关于交换和交换
交换(交换分区)是操作系统耗尽内存的一种解脱。当内存不足时,它会根据一些配置值和当前统计值进行适当的判断,并将一些匿名内存(分配的内存)交换到交换分区。
交换性是系统的一个参数,可以调整交换的优先级。Linux文档描述如下:
摇摆
该控件用于定义内核交换的积极程度
内存页面。较高的值会增加攻击性,较低的值
减少交换量。值0指示内核不要
启动交换,直到空闲页面和文件备份页面的数量减少
比一个区域的最高水位还要高。
默认值为60。
翻译一下就是
这个参数定义了内核交换内存页面的侵略性。较高的值会增加攻击性,而较低的值会减少交换的次数。值为0将指示内核不要使用交换,只有当空闲和文件使用的内存页数小于一个区域的高水位时,才会使用交换。
默认值为60。
至于这里咄咄逼人,我们看的是云里雾里。我只知道这个值的大概意思。在某些环境下,用户总会抱怨为什么Swap用得那么多,而且显然还有很多可用内存。
Linux内存应用
一般来说,Linux内存应用会打上一些标志,对应用进程会有一些影响,这里就不细说了。主要说的是一般的内存应用(用户模式的应用和大多数内核模式的社区都可以等待内存释放)。
__alloc_pages通常会第一次遍历每个内存区域,以找到第一个足够可用的内存块。如果一个区域已满,将搜索下一个区域。单数如果设置了CPUSETS,将触发内存回收。
这里的Swappiness主要在记忆回忆时生效。
回收之道
基本上,回收的一种方法是回收与文件相关的内存,另一种方法是将部分匿名内存(即分配的内存)交换到交换分区。
Linux内存使用的目的之一就是尽可能多地使用内存。文件读写时,文件的缓存会一直保留在系统内存中,直到内存不足,没有逻辑主动释放这部分内存。这样,下次读取缓存的文件时,可以直接从内存中读取,而无需从磁盘进行IO操作,因此文件读取速度会更快。
因此,当仍然有大量可用内存时,内存仍然不足,这将触发回收逻辑,并将部分内存交换到交换分区。
摇摆如何生效
Swappiness用于get_scan_count函数。
以下代码显示,当交换已满时,此参数不起作用。
2195 /*如果我们没有交换空间,请不要扫描其他页面。*/
2196 if(!sc-&gt。may _ swap | | mem _ cgroup _ get _ NR _ swap _ pages(memcg)& lt;= 0) {
2197 scan _ balance = SCAN _ FILE
2198 goto out
2199 }
当Cgroup的mem未达到限制且Swappiness为0时,仅扫描文件缓存。也就是不考虑交换。
2201 /*
2202 *全球回收将交换,以防止即使没有
2203 * swappiness,但memcg用户希望使用此旋钮来
2204 *在以下情况下,完全禁用单个组的交换
2205 *使用内存控制器的交换限制功能将
2206 *太贵了。
2207 */
2208 if(!global _ recovery(sc)和amp& amp!swappiness) {
2209 scan _ balance = SCAN _ FILE
2210转出;
2211 }
当系统接近OOM时,交换性不为0,匿名和文件的内存将被同等扫描。
2213 /*
2214 *不要应用任何压力平衡的聪明
2215 *系统接近OOM,同等扫描匿名和文件
2216 *(除非交换设置与交换不一致)。
2217 */
2218 if(!sc-&gt。优先级和。& ampswappiness) {
2219 scan _ balance = SCAN _ EQUAL
2220转出;
2221 }
当内存达到限制时,将只释放请求的内存。结合前面提到的分支,我们可以知道,当Swappiness为0时,在达到限制之前,只会释放文件缓存,而当达到限制时,会考虑将内存切换到交换。

推荐阅读