反碎片技术和虚拟可移动区域

Linux在内存管理上,存在一个问题,那就是在系统运行很长一段时间后,物理内存中的碎片会越来越多。

1. 内存碎片整理

1.1 什么是内存碎片呢?

内存碎片分为两种,一种是内存页中的碎片,被称为内部碎片;另一种是空闲分散的内存页,凑不齐一个组物理地址连续的空闲内存页,就没办法分配了,这些散落的内存页被称为外部碎片

反碎片技术和虚拟可移动区域_第1张图片

 

1.2 内核引入的反碎片技术

  • 2.6.23 引入成块回收,3.5版本后废除,被碎片整理程序取而代之
  • 2.6.33 引入虚拟可移动区域

其中,不管是成块回收还是碎片整理,它们都是在碎片之后进行处理,而这往往对系统性能是有损耗的,尤其是回收热页的时候。而虚拟可移动区域不同,这是一种预防碎片产生的技术。

1.3 反碎片的工作原理

内核从2.6.24开始引入反碎片技术,试图从最开始就尽可能的防止碎片的产生。它根据页的可移动性将可分配页分为以下三种不同的类型

  • 不可移动页,比如核心内核分配的大多内存
  • 可回收页,不能移动,但可以删除。
  • 可移动页,可以随意移动,如用户空间的页。移动之后,需要更新页表项。

导致碎片的原因就是不可移动的页插在很多连续页组之后,导致其他空闲页不能用。而页加入可移动性之后,就可解决这个问题。

 

2. 虚拟可移动区域

可移动区域(ZONE_MOVABLE)是一个抽象的内存区域,它将物理内存分为两个区域。一个区域用于放置不可移动的页,另一个区域用于放置可移动的页。这样不可移动的页就不能插在移动区域造成碎片了。

那么如何确定两个区域的大小呢?

  • kernelcore参数用于指定不可移动分配的内存数量,指定值保存在required_kernelcore中。
  • movablecore参数用于指定可移动分配的内存数量,计算值存在required_kernelcore中。

如果两个参数都设定,那么required_kernelcore = max(指定值,计算值)。

源码如下

// mm\page_alloc.c
...
static unsigned long __meminitdata arch_zone_lowest_possible_pfn[MAX_NR_ZONES];
static unsigned long __meminitdata arch_zone_highest_possible_pfn[MAX_NR_ZONES];
static unsigned long __initdata required_kernelcore;
static unsigned long __initdata required_movablecore;
static unsigned long __meminitdata zone_movable_pfn[MAX_NUMNODES];
...
/*
 * kernelcore=size sets the amount of memory for use for allocations that
 * cannot be reclaimed or migrated.
 */
static int __init cmdline_parse_kernelcore(char *p)
{
    return cmdline_parse_core(p, &required_kernelcore);
}

/*
 * movablecore=size sets the amount of memory for use for allocations that
 * can be reclaimed or migrated.
 */
static int __init cmdline_parse_movablecore(char *p)
{
    return cmdline_parse_core(p, &required_movablecore);
}

early_param("kernelcore", cmdline_parse_kernelcore);
early_param("movablecore", cmdline_parse_movablecore);

另外函数find_zone_movable_pfns_for_nodes 用于计算进入可移动区域的内存数量。

对一个每个结点来说,zone_movable_pfn[node_id] 表示movable_zone内存域的起始地址,同required_kernelcore一样, 这也是一个关键的变量。

 

参考:

[0] 深入Linux内核架构

 

你可能感兴趣的:(009-Linux内核,002-操作系统,linux,内核,反碎片,虚拟可移动区域,内存碎片)