Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1083672
  • 博文数量: 165
  • 博客积分: 3900
  • 博客等级: 中校
  • 技术积分: 1887
  • 用 户 组: 普通用户
  • 注册时间: 2007-04-06 15:15
文章分类

全部博文(165)

文章存档

2020年(3)

2019年(8)

2017年(2)

2016年(8)

2015年(14)

2013年(15)

2012年(32)

2011年(11)

2010年(14)

2009年(7)

2008年(20)

2007年(31)

分类: LINUX

2013-08-02 13:31:13

linux物理内存的管理采用的是经典的伙伴系统,当然也就存在伙伴系统的问题——内存碎片。

        2.6.32内核compaction原理

当然,此处的内存碎片问题并不算大,因为伙伴系统是以页为单位为管理内存的,碎片也是以“页”为单位,4k的物理内存还算不上是“碎片”。对于用户态的程序,几乎不需要超过4k的连续空间。但是对内核来说,碎片永远都不是好东西。某些硬件相关的操作会需要连续的物理内存,如果无法满足,内核就只能panic。另外,引入compaction的另一个重要因素就是使用hugepage

         4k的页面大小已经出现了很多年了,就像文件系统上1k-4kblock_size一样,都是适应二十年前硬件的容量与速度而出现的,对于现在的硬件来说它们都显得太小了。使用更大的物理页,可以带来两个好处:TLB缓存命中率的提高和page_fault的次数降低。compaction正是为了支持hugepage而出现的。

         下面来看compaction的基本原理。

要获得连续的物理内存只有两个方法,直接释放掉一部分内存,或者重新组织内存。

在内核中的物理内存,有一部分是“可移动”的。


 2.6.32内核compaction原理

                  

内核使用的反碎片技术的基本原理,就是根据页的“可移动性”将页面分组。

关于物理页的是否可移动

         非空闲的 物理内存,当然要么是用户态进程在用,要么内核本身在用。对于前者,进程在访问物理内存的时候,实际上要通过页表的映射来访问。页表是一个可以做文章的地方:如果把一个页移动到另一个地方,如果可以同时修改页表,那么对应用程序就不会有影响。而对于内核访问物理内存时,是通过简单的常量偏移来做的。因此内核使用的物理页面无法移动。

         页移动的流程:

1.         锁定页,以避免在移动页的过程中有进程修改页面。页面记为oldpage

2.         确保“writeback”已经完成

3.         删除当前页面的全部映射,并将指向该页的页表项标记MIGRATION

4.        nbsp; 经过几天的艰苦奋战,终新页,记为newpage

5.         获取radix tree的锁,以阻塞所有试图通过radix tree来访问页面的进程。将radix treeoldpage的指针指向newpage。释放radix tree的锁。

6.         旧页的内容被拷到新页面中,设置新页面的各项标志

7.         将所有页表项指向新页面

在页面移动过程中,old page是被锁定的。

另外,内核怎样知道一个页面是否是可移动的?

分配内存的函数,kmalloc,alloc_pages等在任何地方都可能被调用。内核又是怎样知道在这些地方分配的页面属于哪种类型呢?看这几个函数的原型

void *kmalloc(size_t size, gfp_t flags)

struct page * alloc_pages(gfp_t gfp_mask, unsigned int order)

内核自然不知道kmalloc分配的内存是作什么用途的,但是kernel 开发者知道,一个页面是否可移动,自然也是开发者们告诉内核的。gft_t中有个标志位:GFP_MOVABLE,开发者需要根据相应的内存是否要移动来设置该位。

 

那么该怎样查看系统中当前的碎片情况呢?/proc下已经提供了接口,一方面方便开发者调试,另一方面可以让系统管理员了解当前的系统运行状态。

gaoqiang@c2:~$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      0      0      1      2      0      1      0      1      0      0

Node    0, zone      DMA, type  Reclaimable      0      0      0      0      0      0      0      0      0      0      0

Node    0, zone      DMA, type      Movable      0      0      0      0      0      0      0      0      0      0      3

Node    0, zone      DMA, type      Reserve      0      0      0      0      0      0      0      0      0      1      0

Node    0, zone      DMA, type      Isolate      0      0      0      0      0      0      0      0      0      0      0

Node    0, zone    DMA32, type    Unmovable     56     84     47     59     19      3      1      0      0      1      0

Node    0, zone    DMA32, type  Reclaimable      1      1      0      0      3      1      1      0      0      0      4

Node    0, zone    DMA32, type      Movable     57     33     23     10      4      3      9     18     11      3      2

Node    0, zone    DMA32, type      Reserve      0      0      0      0      0      0      0      0      0      0      1

Node    0, zone    DMA32, type      Isolate      0      0      0      0      0      0      0      0      0      0      0

Node    0, zone   Normal, type    Unmovable    398    398    171     48     28      8      0      0      0      0      0

Node    0, zone   Normal, type  Reclaimable     20     17      6      5      1      0      0      1      3      0      0

Node    0, zone   Normal, type      Movable    354    221    125    101     80     58     10     48      1      0      0

Node    0, zone   Normal, type      Reserve      2      3      1      2      2      2      2      2      2      0      0

Node    0, zone   Normal, type      Isolate      0      0      0      0      0      0      0      0      0      0      0

阅读(1196) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~