经过前面文章的介绍,每个内存管理区都有一个数组watermark,内核中定义了三个watermark来表示当前系统剩余的空闲内存。
WMARK_MIN,
WMARK_LOW,
WMARK_HIGH,
watermark
- high
当剩余内存在high以上时,系统认为当前内存使用压力不大。 - low
当剩余内存降低到low时,系统就认为内存已经不足了,会触发kswapd内核线程进行内存回收处理 - min
当剩余内存在min以下时,则系统内存压力非常大。一般情况下min以下的内存是不会被分配的,min以下的内存默认是保留给特殊用途使用,属于保留的页框,用于原子的内存请求操作。
比如:当我们在中断上下文申请或者在不允许睡眠的地方申请内存时,可以采用标志GFP_ATOMIC来分配内存,此时才会允许我们使用保留在min水位以下的内存。
对页面回收的影响
- kswapd周期回收机制
从上面对三种水位的介绍,high水位时内存很充足,内核不用特意做回收的动作,那么它存在的意义是什么呢?
实际上,当内存降低到low watermark时,内核线程kswapd开始进行回收页面,但回收页面要回收到什么程度为止呢?这时high watermark存在的意义就体现出来了,当kswapd回收页面发现此时内存终于达到了high水位,那么系统认为内存已经不再紧张了,所以将会停止进一步的操作。 - 内存紧缺直接回收机制
如果内存达到或者低于min watermark时,会触发内核直接回收操作(direct reclaim)
水位的设定
水位的设定与系统保留内存的数量有关,存放在min_free_kbytes中,它在内核初始化时设置,取决于直接映射区物理内存的数量。
min_free_kbytes = 16 ∗ 直 接 映 射 区 内 存 s i z e \sqrt{16*直接映射区内存size} 16∗直接映射区内存size(KB)
每个管理区(zone)中的min watermark是与min_free_kbytes有关的。
比如:
我使用的平台上,直接映射区上有两个管理区:ZONE_DMA/ZONE_NORMAL,那么他们中的min水位就是按照大小比例来分配的。两个管理区的min watermark相加应该等于min_free_kbytes。通过系统节点/proc/sys/vm/min_free_kbytes也可以看到系统总的保留物理内存大小。
计算得到min watermark后,再根据min的大小分别算出每个zone的low和high水位标记。
计算方法:
low = min × 5 / 4;
high = min × 3 / 2;