# 页分配器

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

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

最原始的版本中页结构体是作为一个大的静态数组存放在内存中的，而随着内存变大，空洞变多，静态数组显然不符合设计理念。之后则提出 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)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://richardweiyang-2.gitbook.io/kernel-exploring/nei-cun-guan-li/00-memory_a_bottom_up_view/00_page_allocator.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
