我们说了,内存泄露的危害,以及可能在内存不足的时候,系统会做的事情,无非就是OOM杀死进程或者内存回收

对于OOM,其实很简单,就是系统杀死占用大量内存的进程,释放其给更需要的进程

对于内存回收,则是释放可以回收的内存,比如我们说的缓存和缓冲区 Buffer和Cache,就是可回收资源,又被称为文件页

大部分的文件页,都可以直接回收,少部分被修改过的文件页,则需要先写入磁盘,在进行回收

写入磁盘,对于应用程序来说,可以调用fsync,进行脏页的同步

或者交给系统,由内核线程 pdflush负责这些脏页的刷新

除了这种文件页的刷新获取,还有其他的内存可以回收,比如在开启Swap之后,应用程序分配的堆内存,俗称的匿名页,也是可以回收的

在Swap机制中,会将不经常访问的内存先写入到磁盘中,然后释放其,给更加需要的进程使用,再次访问的时候,直接从磁盘读入就可以了

那么我们就针对Swap机制,进行一下了解

Swap很简单,就是讲磁盘当做内存来使用,这个过程中分为了换出和换入两个部分

换出就是将暂时不用的内存存储到磁盘,并释放这些内存

换入就是讲内存再次读到内存中去

Swap就是讲系统的可用内存变大了,即使服务器的内存不足,也可以运行大内存应用程序

现在的快速开机,就是基于Swap,将系统内存存入磁盘,开机的时候,直接加载就可以了

那么Linux触发Swap的机制是什么时候呢?

或者说如何衡量内存是否紧张呢?

常见的场景就是,大内存的分配请求,但是剩余内存不足,这就需要触发Swap,这个过程被称为直接内存回收

除了主动触发,还会有专门的内存线程还定期的回收内存,就是kswapd0,为了衡量内存的使用情况,kswapd0定义了三个内存阈值,分别是,页最小阈值 min,页低阈值 low,页高阈值 high

他们三者和触发Swap的关系如下

图片

如果free内存低于min,则说明内存耗尽

如果大于min小于low,说明需要swap立即回收

如果在low和high之间,就说明还不错,满足内存使用,如果剩余内存大于high,说明毫无压力

如何设置三者,可以通过/proc/sys/vm/中的min_free_kbytes中设置

然后其他两个阈值,就是通过页最小阈值计算生成的

pages_low = pages_min*5/4

pages_high = pages_min*3/2

那么我们查看一下对应的内存和Swap的关系

我们在处理器的NUMA架构中,每个处理器都有自己的内存空间

每一个Node的本次空间,进一步可以分为不同的内存域,比如DMA,普通内存区,伪内存区等

图片

那么我们如何查看对应的内存不同阈值呢?

其实在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

上面在Node0上,标明了min low high三个阈值,以及free页

剩下的还有

nr_zone_active_anon 和 nr_zone_inactive_anon,分别是活跃和非活跃的匿名页数。nr_zone_active_file 和 nr_zone_inactive_file,分别是活跃和非活跃的文件页数。

上面看出来,free大于页高阈值,所以不会触发swap

当然,某个Node不足的时候,系统可以从其他的Node寻找空闲内存,或者从本次内存中回收内存

这个可以利用同一目录下的zone_reclaim_mode 设置

0是默认,即都可以

1 2 4表示回收本地内存 2表示回写脏数据回收内存, 4表示可以用Swap方式回收内存

这样,就是基本的Swap的使用

最后,在选择匿名页的回收还是文件页的回收上,Linux也提供了对应的选项,配置Swap的回收倾向

在上面的/proc/sys/vm中,我们可以读取swappiness选项,调整使用Swap的积极程度

0-100,数值越大,越倾向于使用Swap,数值越小,越不愿意使用Swap

但是即使设置为0,当小于页高的时候,还是会触发Swap

总结一下

Linux利用文件页回收和匿名文件Swap化来分配内存

对于这个Swap,可以设置min_free_kbytes来回收内存阈值

还可以设置swappiness来调整文件页和匿名页的回收倾向

在Numa架构下,每个Node都有自己的内存空间,本地内存不够的时候,回收策略可以利用zone_reclaim_mode来调整

对JVM来说为何要关闭Swap,则是和JVM的gc相关,在gc的时候会遍历所有用到的堆内存,如果Swap,就会有磁盘IO

发表评论

邮箱地址不会被公开。 必填项已用*标注