深入理解Linux内核个人小结8---内存区管理

时间:2023-01-11 21:38:22

一. 综述:

     静态内存:用来存放内核代码级静态内核数据结构的物理内存部分。如0-1MB部分用来存储BIOS相关东西及保留页框部分(页框0用于存放BIOS加电自检例程)。1-3MB存放Linux内核代码及相应的数据结构。

    动态内存:除去静态内存即为动态内存。

    动态内存管理主要包括三部分: 页框管理,内存区管理, 非连续内存区管理。



二. 页框管理:

    1. 非一致内存访问(NUMA)-->内存节点-->内存管理区-->伙伴系统(页高速缓存)

    2. 内存区分为三种类型:ZONE_DMA(ISA总线等),ZONE_NORMAL(常规),ZONE_HIGHMEM(高端内存区管理)

        ZONE_HIGHMEM:页框到内存区映射的三种方式:

        <1> 永久映射: 主内核页表中有一个专门的表项pkmap_page_table用来存放从高端物理地址到线性地址的映射(通过Hash表确定映射关系)。

        <2>临时映射:通过“窗口”映射到内核地址空间。但留给内核映射的窗口非常少。每个CPU都有自己的13个窗口集合。(类似于常量指针)

       <3>非连续映射:

     3. 管理区分配器:必须保护保留页框池,内存不足时进行回收再分配。

         分配方式:

             每CPU页高速缓存:两种hot与cold,释放时都是释放到hot

             伙伴系统: 11个链表    大小从 4KB 到   4MB   (主要用于处理外碎片的情形) 

    4. 保留页框池与内存池:

        保留页框池:用于满足中端,临界区等不可阻塞的临界区内存申请。     内存分配时若有足够空间则直接分配,若空间不够则暂时阻塞申请进程,通过回收内存再进行分配(有可能回收不到足够内存导致分配失败)。但对某些内存控制路径,其不能被阻塞,其申请操作为原子请求,若空间不够则失败。为了减少此情况(分配失败)的发生,内核为原子分配请求保留了一个页框池,只有在内存不足时才使用。

        内存池:动态内存储备,只能被特定的内核成分(拥有者)使用。


三.  内存区管理:

     1. 为了处理内碎片,并非基于伙伴系统,其自身是独立的。 主要用于处理高速缓存。

     2. 注意    高速缓存,Slab,对象间的对应关系。高速缓存描述符链表,每一项中的slab及对象的大小是一致的,但项间的大小是不同的。


四.  非连续的内存区管理:

     目的:将非连续的页框映射到连续的线性地址。(通过修改页表来实现,但导致打乱了内核页表)

     注意:大于896MB的内存区间的分布情况

        非连续内存区--->永久内核映射--->临时内核映射(也称固定映射)。