Linux内存警戒线&内存回收
min_free_kbytes = sqrt(lowmem_kbytes * 16) = 4 * sqrt(lowmem_kbytes)(注:lowmem_kbytes即可认为是系统内存大小)
另外,计算出来的值有最小最大限制,最小为128K,最大为64M,但是通过proc接口设置就没这个限制。(当前centos3.10中默认为66M)
/* don't ever allow to reserve more than 5% of the lowmem */
min_free_kbytes的主要用途是计算影响内存回收的三个参数 watermark[min/low/high]
每个内存管理区(zone)都有一个数组watermark,内核定义了三个watermark来表示当前系统色好难过与空闲内存。
1) watermark[high] > watermark [low] > watermark[min],各个zone各一套(以page为单位的)
2)在系统空闲内存低于 watermark[low]时,开始启动内核线程kswapd进行内存回收(每个zone一个),直到该zone的空闲内存数量达到watermark[high]后停止回收。如果上层申请内存的速度太快,导致空闲内存降至watermark[min]后,内核就会进行direct reclaim(直接回收),即直接在应用程序的进程上下文中进行回收,再用回收上来的空闲页满足内存申请,因此实际会阻塞应用程序,带来一定的响应延迟,而且可能会触发系统OOM。这是因为watermark[min]以下的内存属于系统的自留内存,用以满足特殊使用,所以不会给用户态的普通申请来用。
watermark[min] = min_free_kbytes换算为page单位即可,假设为min_free_pages。(因为是每个zone各有一套watermark参数,实际计算效果是根据各个zone大小所占内存总大小的比例,而算出来的per zone min_free_pages)
watermark[low] = watermark[min] * 5 / 4
watermark[high] = watermark[min] * 3 / 2
后台内存回收(kswapd):在物理内存紧张的时候,会唤醒 kswapd 内核线程来回收内存,这个回收内存的过程异步的,不会阻塞进程的执行。
直接内存回收(direct reclaim):如果后台异步回收跟不上进程内存申请的速度,就会开始直接回收,这个回收内存的过程是同步的,会阻塞进程的执行。
如果直接内存回收后,空闲的物理内存仍然无法满足此次物理内存的申请,那么内核就会触发 OOM (Out of Memory)机制,根据算法选择一个占用物理内存较高的进程,然后将其杀死,释放内存资源,直到释放足够的内存。
int main(int argc, char *argv[])
size = strtoull(argv[1], NULL, 10);
printf(" argv[1]=%s not good\n", argv[1]);
char *buff = (char *) malloc(size * UNIT);
printf(" we malloced %d Mb\n", size);
for (i = 1; i < (size * UNIT); i++) {
关闭drop_caches后台进行,防止后模一分钟周期清除cache
mv /b_iscsi/bin/RAM_arrange.sh /b_iscsi/bin/RAM_arrange.sh.bak
cat /mnt/backupSystem/test.txt > /dev/null
开始消耗内存测试,测试当pages free低于watermark[low]时,cache回收
当前pages free已几乎接近watermark[low],而cache还未回收,当前low以上可分配空间最大值为:41.1875
((16683 - 6102) + (14936 - 14973)) × 4 ÷ 1024 = 41.1875
因此,分配一个大于该值的空间则可使得free内存低于low,从而触发异步kswapd进程开始回收内存(cache)。
空间立刻申请成功,且cache空间持续下降,而pages free持续增长,直至达到high后停止增长、cache停止下降。
所以,当pages free低于low后开始内存回收的结论得到证实。
继续消耗内存使得cache空间得到全部释放后,当低于min后是否可以触发OOM。
持续消耗内存发现其中一个操作出现明显卡顿,且前后pages free增长,因此怀疑消耗内存低于了min水平线。
考虑将min_free_kbytes的值设置变大后会有什么影响?
在总内存4G的设备中设置min_free_kbytes为1G,如图:
持续进行内存消耗后,发现pages free在还未达到low以后,设备出现了hang机,所有指令均无法执行。
正常情况下,系统应该是在free低于min后OOM杀死进程得到空间释放,为什么还有空余内存空间,反而无法得到内存呢?
这个问题经过几天的资料查询,依然未得到答案,怀疑的地方有两点:
min_free_kbytes过大导致,官方建议该值用用不要超过%5的lowmem,但并没有说明原因,需要进一步查看预研











浙公网安备 33010602011771号