# 页分配器

页分配器是一个相对牵着概念较多的层次，也可以说正是这个层次把物理上的内存差异屏蔽，从而向用户呈现了一致的使用接口。

第一个让我好奇的是页结构体究竟是存放在哪里的？

最原始的版本中页结构体是作为一个大的静态数组存放在内存中的，而随着内存变大，空洞变多，静态数组显然不符合设计理念。之后则提出 SPARSEMEM的概念，按实际情况分配页结构体。

[寻找页结构体的位置](https://richardweiyang-2.gitbook.io/kernel-exploring/nei-cun-guan-li/00-memory_a_bottom_up_view/00_page_allocator/03-sparsemem)

知道页结构体在那里，顺便来瞥一眼结构体的样子。为啥说是瞥一眼呢？因为这个结构体实在是太大（乱）了。为了满足各种需求，这个结构 中进行了多重复用。先放在这里，作为一个参考文档把。

[眼花的页结构体](https://richardweiyang-2.gitbook.io/kernel-exploring/nei-cun-guan-li/00-memory_a_bottom_up_view/00_page_allocator/10-page_struct)

所谓的内存物理差异无非就两点：

* 硬件是否能访问
* 访问速度的差异

而这两点对应到软件上的概念是：

* ZONE
* NUMA NODE

那内核中是如何把这两个信息保存起来，并用来指导内存非配的呢？

这就需要大名鼎鼎的pg\_data\_t结构体出场了。所有的页分配工作都是基于这个数据结构的信息所作出的。

[Node-Zone-Page](https://richardweiyang-2.gitbook.io/kernel-exploring/nei-cun-guan-li/00-memory_a_bottom_up_view/00_page_allocator/05-node_zone_page)

有了这样的概况之后，我们就可以来看看页是如何初始化和被分配的了。

[传说的伙伴系统](https://richardweiyang-2.gitbook.io/kernel-exploring/nei-cun-guan-li/00-memory_a_bottom_up_view/00_page_allocator/06-page_alloc)

将内存划分为node/zone之后，分配内存时是不是有办法去控制从哪个node哪个zone上去分配呢？答案是有的。

[GFP的功效](https://richardweiyang-2.gitbook.io/kernel-exploring/nei-cun-guan-li/00-memory_a_bottom_up_view/00_page_allocator/12-gfp_usage)

为了更好管理内存，内核中会给分配出去的内存做一些标记，这样方便在回收，出错等时候判断内存的用途。

为了更好的理解内存管理中的代码流程，我们需要了解[页分配器的用户们](https://richardweiyang-2.gitbook.io/kernel-exploring/nei-cun-guan-li/00-memory_a_bottom_up_view/00_page_allocator/11-users_of_buddy)
