避免物理内存碎片化 - 内存紧缩

原文地址 http://lwn.net/Articles/368869/


长期存在的内存碎片问题,已经有多篇文章提及了。简单的说:当系统运行一段时间后,空闲页面趋向于散落在不连续的空间,很难再有足够长的连续物理内存页面分配。内核开发者已经下了很多工夫,减少大块连续物理内存的分配,因此大部分内核功能并不会受到页面碎片化的影响。但是仍然存在对大块连续物理内存的需要,在内存碎片化系统上的内存分配,因此可能失败。

过去几年,内核开发者们做出了各种努力来解决这个问题,导致了了ZONE_MOVABLE lumpy reclaim技术的出现。同时还有许多工作正在进行中,特别是如何恢复碎片化内存为可用的大块内存领域。Mel Gorman最近提交了一组patch来实现内存紧缩。下面我们来看看这个patch是如何工作的。

想像我们有如下内存区

在这里,白色表示页面是空闲的,而那些红色则表示页面已经分配出去。我们可以看出,这个内存区已经严重的碎片化了,超过两个页面的连续内存块的分配都会失败,比如分配4个页面的块会导致失败。实际上,甚至两个页面的分配都会失败,因为虽然看上去有连续的内存块,但是没有一对页面符合对齐要求

现在是紧缩代码派上用场的时候了。这段代码运行两个算法:第一个从zone的起起始位置开始扫描,建立一个可以移动的已分配页面链表:



同时从分区的尾部,运行另外一个算法:创建一个空闲页面链表,用做页面迁移的目标页框。



最后两个算法在zone的某个地点相遇。在这一点,我们调用页面迁移代码,把前面使用过的page移动到zone的后面空闲页面,移动后的效果如下图



现在我们有一个漂亮的,8个并且是连续分布的空闲页面,可以用来满足8个页面以下的内存分配。

当然,这里的图示简化了整个过程,在实际系统中,内存区可能非常的大,因此有更多地工作需要完成。


记住,在实际系统中并不是所有的页面都可以移动。只有那些通过非直接映射的页面才可以被移动,这包括内核的vmalloc区和用户空间的映射页面。需要修改相应的页表项。 内核使用的直接映射是不能移动的,尽管他们可能被回收(可以在需要的时候释放)。一个不可移动的页面就可以让一大段内存段变得碎片化,且无法通过回收变连续。幸运的是内核已经把内存区分成了movable和unmovable两个区,这样我们基本就不用考虑non-movable带来的影响。

紧缩算法可以通过两种方式启动:第一,向/proc/sys/vm/compact_node写入一个节点号,紧缩操作将运行在相应的NUMA节点上。另一方面,如果系统在分配内存时失败:在这种情况下,紧缩操作可以代替 直接回收页面操作来获取大的连续物理内存。如果没有明显的触发动作,那么紧缩算法可能一直保持空闲,因为移动页面是需要花费代价的,除非必要最好避免执行这个操作。


因为内存紧缩属于内存管理代码,所以需要很长的时间测试,验证和讨论。这个补丁有可能进入主线内核。


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值