page compaction原理
Posted Loopers
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了page compaction原理相关的知识,希望对你有一定的参考价值。
参考: 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的步骤:
- 代码中运行两个独立分扫描队列,第一个扫描队列从zone的底部从下往上扫描,一边扫描一边讲可以移动(Moveable)的页放入到此链表中,可以将此链表称为迁移扫描器
- 同时在zone的顶部页存在一个扫描器(空闲扫描器),从顶部到底部将空闲的页假如到空闲链表中。
- 当迁移扫描器从底部到顶部扫描,空闲扫描器从顶部到底部扫描,最终迁移和空闲扫描器最终会相遇。当迁移扫描器和空闲扫描器相遇之后,就意味着page compaction结束了。剩下的工作就是将迁移扫描器的page copy到空闲扫描器,然后接触迁移扫描器的页面对应关系。最终会形成如下的结果
这样一来我们就拥有了一个连续的8页的可用空间了。可以满足更高阶的分配需求了。
当然page compation有两种触发方式:
- 当分配page的时候,在LOW水位出现分配失败的时候,会尝试slowth分配的,在当中就会出现page compaction的流程
- 工程师可以通过echo x > /proc/sys/vm/compact_memory来启动page compaction的动作,启动后内核线程kcompactd*就会启动来进行页面整理的
此时当我在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还是有效的。
以上是关于page compaction原理的主要内容,如果未能解决你的问题,请参考以下文章
MySQL原理 - InnoDB引擎 - 行记录存储 - Off-page 列