系统的Swap变高了(上)

网友投稿 301 2022-11-04


系统的Swap变高了(上)

问题:当发生了内存泄露时,或者运行了大内存的应用程序,导致系统的内存资源紧张时,系统又会如何应对?

内存紧张时,会导致两种可能结果,内存回收和OOM杀死进程。

内存资源紧张导致的OOM(Out Of Memory),相对容易理解,指的是系统杀死占用大量内存的进程,释放这些内存,再分配给其他跟需要的进程。

内存回收就是系统释放掉可回收的内存。比如缓存和缓冲区。就属于可回收内存。它们在内存管理中,通常被叫做文件页(FileBacked Page)

大部分文件页,都可以直接回收,以后有需要时,再从磁盘重新读取就可以了。而那些被应用程序修改过,并且暂时还没写入磁盘的数据(也就是脏页),就得先写入磁盘,然后才能进行内存释放。

这些脏页,一般可以通过两种方式写入磁盘。

可以在应用程序中,通过系统调用 fsync ,把脏页同步到磁盘中;也可以交给系统,由内核线程 pdflush 负责这些脏页的刷新。

除了缓存和缓冲区,通过内存映射获取的文件映射页,也是一种常见的文件页。它也可以被释放掉,下次再访问的时候,从文件重新读取。

问题:除了文件页外,还有没有其他的内存可以回收呢?比如,应用程序动态分配的堆内存,也就是我们在内存管理中说到的匿名页(Anonymous Page),是不是也可以回收呢?

这些内存不能直接释放,很可能还要再次被访问,所以不能直接回收。

但是,如果这些内存存在分配后很少被访问,也是一种资源浪费。

其实,这正是Linux的Swap机制。Swap 把这些不常访问的内存先写到磁盘中,然后释放这些内存,给其他更需要的进程使用。再次访问这些内存时,重新从磁盘读入内存就可以了。

一、Swap原理

Swap 就是把一块磁盘空间或者一个本地文件(以下以磁盘为例),当成内存来使用。它包括换出和换入两个过程。

换出:就是把进程暂时不用的内存数据存储到磁盘中,并释放这些数据占用的内存。换入:是在进程再次访问这些内存的时候,把它们从磁盘读到内存中来。

所以,Swap其实是把系统的可用内存变大了。这样,即使服务器的内存不足,也可以运行大内存的应用程序。

疑问:前期内存昂贵,需要开启swap来使系统可用内存变大,现在内存价格便宜了,是不是swap就无用武之地了呢?

当然不是,事实上,内存再大,对于应用程序来说,也有不够用的时候。

典型场景:

即使内存不足时,有些应用程序也并不想被OOM杀死,而是希望能缓一段时间,等待人工介入,或者等系统自动释放其他进程的内存,再分配给它。

除此之外,我们常见的笔记本电脑的休眠和快速开机的功能,也基于swap。休眠时,把系统的内存存入磁盘,这样等到再次开机时,只要从磁盘中加载内存就可以。这样就省去了很多应用程序的初始化过程,加快了开机速度。

疑问:既然 Swap 是为了回收内存,那么 Linux 到底在什么时候需要回收内存呢?前面一直在说内存资源紧张,又该怎么来衡量内存是不是紧张呢?

场景:

有新的大块内存分配请求,但是剩余内存不足。这个时候系统就需要回收一部分内存(比如前面提到的缓存),进而尽可能地满足新内存请求。这个过程通常被称为直接内存回收。

除了直接内存回收,还有一个专门的内核线程用来定期回收内存,也就是 ​​kswapd0​​。为了衡量内存的使用情况,kswapd0 定义了三个内存阈值(watermark,也称为水位),分别是:

页最小阈值(​​pages_min​​​)、页低阈值(​​pages_low​​​)和页高阈值(​​pages_high​​)。剩余内存,则使用 pages_free 表示。

三者关系图如下:

kswapd0 定期扫描内存的使用情况,并根据剩余内存落在这三个阈值的空间位置,进行内存的回收操作。

剩余内存 < 页最小阈值:说明进程可用内存耗尽了,只有内核才可以分配内存。页最小阈值 < 剩余内存 < 页低阈值:说明内存压力比较大,剩余内存不多了。这时 kswapd0 会执行内存回收,直到剩余内存大于高阈值为止。页低阈值 < 剩余内存 < 高阈值:说明内存有一定压力,但还可以满足新内存请求。剩余内存 > 页高阈值:说明剩余内存比较多,没有内存压力

可以看到,一旦剩余内存小于页低阈值,就会触发内存的回收。这个页低阈值,其实可以通过内核选项 ​​/proc/sys/vm/min_free_kbytes​​ 来间接设置。min_free_kbytes 设置了页最小阈值,而其他两个阈值,都是根据页最小阈值计算生成的,计算方法如下

pages_low = pages_min*5/4pages_high = pages_min*3/2

二、NUMA 与 Swap

问题:很多情况下,明明发现了 Swap 升高,可是在分析系统的内存使用时,却很可能发现,系统剩余内存还多着呢。为什么剩余内存很多的情况下,也会发生 Swap 呢?其实正是处理器的NUMA(Non-Uniform Memory Access)架构导致的。

在 NUMA 架构下,多个处理器被划分到不同 Node 上,且每个 Node 都拥有自己的本地内存空间。

而同一个 Node 内部的内存空间,实际上又可以进一步分为不同的内存域(Zone),比如直接内存访问区(DMA)、普通内存区(NORMAL)、伪内存区(MOVABLE)等,如下图所示:

既然 NUMA 架构下的每个 Node 都有自己的本地内存空间,那么,在分析内存的使用时,也应该针对每个 Node 单独分析。

可以通过​​numactl​​命令,查看处理器在Node的分布情况,以及每个Node的内存使用情况。

$ numactl --hardwareavailable: 1 nodes (0)node 0 cpus: 0 1node 0 size: 7977 MBnode 0 free: 4416 MB...

输出显示,系统中只有一个Node,也就是Node 0,而且编号为0和1的两个CPU,都位于Node 0上。另外,Node 0的内存大小为7977MB,剩余内存为4416MB

疑问:NUMA 的架构跟Swap有什么关系?

实际上,前面提到的三个内存阈值(页最小阈值、页低阈值和页高阈值),都可以通过内存域在 proc 文件系统中的接口 ​​/proc/zoneinfo​​ 来查看。

$ cat /proc/zoneinfo...Node 0, zone Normal pages free 227894 min 14896 low 18620 high 22344... nr_free_pages 227894 nr_zone_inactive_anon 11082 nr_zone_active_anon 14024 nr_zone_inactive_file 539024 nr_zone_active_file 923986...

输出中有大量指标,重要的几个如下:

pages处的min、low、high:就是上面提到的三个内存阈值,而 free 是剩余内存页数,它跟后面的 nr_free_pages 相同。nr_zone_active_anon 和 nr_zone_inactive_anon:分别是活跃和非活跃的匿名页数。nr_zone_active_file 和 nr_zone_inactive_file:分别是活跃和非活跃的文件页数。

从这个输出结果可以发现,剩余内存远大于页高阈值,所以此时的 kswapd0 不会回收内存。

当然,某个 Node 内存不足时,系统可以从其他 Node 寻找空闲内存,也可以从本地内存中回收内存。具体选哪种模式,可以通过 ​​/proc/sys/vm/zone_reclaim_mode​​ 来调整。

默认的 0 ,也就是刚刚提到的模式,表示既可以从其他 Node 寻找空闲内存,也可以从本地回收内存。1、2、4 都表示只回收本地内存,2 表示可以回写脏数据回收内存,4 表示可以用 Swap 方式回收内存。

三、swappiness

这些回收的内存既包括了文件页,又包括了匿名页。

对文件页的回收,当然就是直接回收缓存,或者把脏页写回磁盘后再回收。而对匿名页的回收,其实就是通过 Swap 机制,把它们写入磁盘后再释放内存。

疑问:有两种不同的内存回收机制,在实际回收内存时,到底该先回收哪一种呢?

其实,Linux提供了一个​​/proc/sys/vm/swappiness​​ 选项,用来调整使用 Swap 的积极程度。

swappiness 的范围是 0-100,数值越大,越积极使用 Swap,也就是更倾向于回收匿名页;数值越小,越消极使用 Swap,也就是更倾向于回收文件页。

四、总结

在内存资源紧张时,Linux 通过直接内存回收和定期扫描的方式,来释放文件页和匿名页,以便把内存分配给更需要的进程使用。

文件页的回收比较容易理解,直接清空,或者把脏数据写回磁盘后再释放。而对匿名页的回收,需要通过 Swap 换出到磁盘中,下次访问时,再从磁盘换入到内存中。

可以设置 ​​/proc/sys/vm/min_free_kbytes​​​,来调整系统定期回收内存的阈值(也就是页低阈值),还可以设置 ​​/proc/sys/vm/swappiness​​,来调整文件页和匿名页的回收倾向。

在 NUMA 架构下,每个 Node 都有自己的本地内存空间,而当本地内存不足时,默认既可以从其他 Node 寻找空闲内存,也可以从本地内存回收。

可以设置 ​​/proc/sys/vm/zone_reclaim_mode​​ ,来调整 NUMA 本地内存的回收策略。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:系统swap变高了(下)
下一篇:汽车价格查询API(汽车价格查询网站)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~