参考: https://lwn.net/Articles/368869/
先看一个例子:
如果你的ubuntu机器经过长时间运行,比如1个月没关机,这时候你去看buddinfo和pagetypeinfo的信息。
root@root# cat /proc/buddyinfo
Node 0, zone DMA 3 3 1 1 3 2 0 0 1 1 3
Node 0, zone DMA32 12996 3696 1157 87 24 6 0 0 0 0 0
Node 0, zone Normal 82836 13398 1269 269 8 1 0 0 0 0 0
root@root# cat /proc/pagetypeinfo
Page block order: 9
Pages per block: 512
Free pages count per migrate type at order 0 1 2 3 4 5 6 7 8 9 10
Node 0, zone DMA, type Unmovable 3 3 1 1 3 2 0 0 1 0 0
Node 0, zone DMA, type Movable 0 0 0 0 0 0 0 0 0 1 3
Node 0, zone DMA, type Reclaimable 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA, type HighAtomic 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA, type CMA 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA, type Isolate 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA32, type Unmovable 568 212 115 60 24 6 0 0 0 0 0
Node 0, zone DMA32, type Movable 12389 3475 1040 27 0 0 0 0 0 0 0
Node 0, zone DMA32, type Reclaimable 39 9 2 0 0 0 0 0 0 0 0
Node 0, zone DMA32, type HighAtomic 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA32, type CMA 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA32, type Isolate 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone Normal, type Unmovable 88 161 288 45 1 1 0 0 0 0 0
Node 0, zone Normal, type Movable 82530 13055 902 159 0 0 0 0 0 0 0
Node 0, zone Normal, type Reclaimable 311 182 52 51 2 0 0 0 0 0 0
Node 0, zone Normal, type HighAtomic 0 0 27 14 5 0 0 0 0 0 0
Node 0, zone Normal, type CMA 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone Normal, type Isolate 0 0 0 0 0 0 0 0 0 0 0
Number of blocks type Unmovable Movable Reclaimable HighAtomic CMA Isolate
Node 0, zone DMA 1 7 0 0 0 0
Node 0, zone DMA32 15 882 119 0 0 0
Node 0, zone Normal 148 6679 312 1 0 0
可以很明显看见order=0的页很多,而order逐渐增大的发现页越来越少。比如order=10的页在Noraml中已经没有了。
这就导致了一个问题:
当我们需要申请一大块连续的物理内存的时候,就会出现无法找到一个连续的大块内存,剩下的大多数都是一页一页零散的内存了。这种问题就是内存碎片问题了。
为了解决内存碎片问题,linux内核引入了page compaction技术,俗称页块整理。整理的原理如下:
假设现在有一个zone的内存布局内部如下:其中red 区域代表的是已经使用的,white是空闲的
可以清晰的看见,所属的空闲区域连续的最大是2个page。如果从该zone中分配四个连续的内存区域,就会出现必然失败的。有可能分配两个连续的页面也有可能失败,如果考虑对齐的话。
page compaction的步骤:
这样一来我们就拥有了一个连续的8页的可用空间了。可以满足更高阶的分配需求了。
当然page compation有两种触发方式:
此时当我在ubuntu上执行echo 1 > /proc/sys/vm/compaction_memory的时候,ubuntu就会启动kcompactd0内核线程来执行页面整理的。咋们来看下最后的结果
root@root# cat /proc/pagetypeinfo
Page block order: 9
Pages per block: 512
Free pages count per migrate type at order 0 1 2 3 4 5 6 7 8 9 10
Node 0, zone DMA, type Unmovable 3 3 1 1 3 2 0 0 1 0 0
Node 0, zone DMA, type Movable 0 0 0 0 0 0 0 0 0 1 3
Node 0, zone DMA, type Reclaimable 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA, type HighAtomic 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA, type CMA 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA, type Isolate 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA32, type Unmovable 186 129 98 60 24 6 0 0 0 0 0
Node 0, zone DMA32, type Movable 1350 1320 1184 799 342 88 7 1 0 0 0
Node 0, zone DMA32, type Reclaimable 68 47 19 7 1 0 0 0 0 0 0
Node 0, zone DMA32, type HighAtomic 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA32, type CMA 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone DMA32, type Isolate 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone Normal, type Unmovable 318 473 493 244 17 1 0 0 0 0 0
Node 0, zone Normal, type Movable 7452 9250 7096 4037 1032 74 4 0 0 0 0
Node 0, zone Normal, type Reclaimable 621 406 321 211 20 1 0 0 0 0 0
Node 0, zone Normal, type HighAtomic 0 0 27 14 5 0 0 0 0 0 0
Node 0, zone Normal, type CMA 0 0 0 0 0 0 0 0 0 0 0
Node 0, zone Normal, type Isolate 0 0 0 0 0 0 0 0 0 0 0
Number of blocks type Unmovable Movable Reclaimable HighAtomic CMA Isolate
Node 0, zone DMA 1 7 0 0 0 0
Node 0, zone DMA32 15 882 119 0 0 0
Node 0, zone Normal 148 6679 312 1 0 0
root@root# cat /proc/buddyinfo
Node 0, zone DMA 3 3 1 1 3 2 0 0 1 1 3
Node 0, zone DMA32 1604 1496 1301 866 367 94 7 1 0 0 0
Node 0, zone Normal 8422 10129 7937 4506 1074 76 4 0 0 0 0
可以看到order逐渐增加可以看见有很多空闲的page了。而且movebale order=0得也在减少,order=2, 3, 4 , 5在增加。这就说明了page compation还是有效的。