复习笔记|第八章 Linux存储器管理《操作系统原理教程》

发布时间 2023-08-07 14:02:29作者: LateSpring

参考教材:《操作系统原理教程(第4版)》刘美华 翟岩龙著

大纲问题回答(精简版)

1. 进程地址空间的划分?管理进程私有地址空间的数据结构?链接虚拟内存区域的单链表和红黑树。指向映射文件对象的指针字段?指向进程页目录表的指针字段?

进程地址空间的管理
◼ 32位机,每个进程的地址空间为4GB。
进程的私有地址空间是前3G,进程的公有地址空间是后1G的内核虚空间
◼ 内核1GB虚空间中的前896MB用来映射物理内存的前896MB,因此前896MB的内存物理地址等于内核虚地址减去0xc0000000。后128MB的虚空间实现对超过896MB的物理内存的映射。
◼ 借助128MB高端内存地址空间可以访问所有物理内存。
◼ 基本思想:借一段地址空间,建立临时地址映射,用完后释放,达到这段地址空间可以循环使用,访问所有物理内存。
image.png
虚拟内存区域
管理进程私有地址空间的数据结构:虚拟内存区域描述符vm_area_struct
◼ 需用一组虚拟内存区域描述符vm_area_struct来描述进程地址空间的使用情况。
◼ 类似于Windows的虚拟地址描述符VAD

struct vm_area_struct {
    struct mm_struct * vm_mm; 虚拟内存描述符
    unsigned long vm_start; /*起始地址*/
    unsigned long vm_end; /*结束地址*/
    struct vm_area_struct *vm_next; /*单链表*/
    struct rb_node vm_rb; /*红-黑树*/
    struct file * vm_file; 映射文件时指向文件对象
    ……
}

红黑树
◼ 红黑树是一棵排好序的平衡二叉树。
◼ 必须满足四条规则:①树中的每个节点或为红或为黑;②树的根节点必须为黑;③红节点的孩子必须为黑;④从一个节点到后代诸叶子节点的每条路径,都包含相同数量的黑节点,在统计黑节点个数时,空指针也算作黑节点。
◼ 这四条规则保证:具有n个节点的红黑树,其高度至多为2*log(n+1)。
新插入的节点一定是红色的叶子节点
单链表+红黑树
◼ 当插入或删除一个虚拟内存区域时,
◼ 内核通过红黑树搜索其相邻节点,并用搜索结果快速更新单链表。
红黑树用来快速确定含有指定地址的虚拟内存区域
单链表用来扫描整个虚拟内存区域集合

虚拟内存描述符的数据结构类型:

struct mm_struct { 
    struct vm_area_struct *mmap; 
    struct rb_root mm_rb; /*指向红-黑树的根*/
    pgd_t *pgd; /*指向页目录表*/
    atomic_t mm_users; /*次使用计数器*/
    atomic_t mm_count; /*主使用计数器*/
    struct list_head mmlist; 双向链表
    unsigned long start_code, end_code; /*可执行代码所占用的地址区间*/
……};

2. Linux堆的管理:malloc( ),free( )。

malloc(size): 请求size字节的内存。成功时,返回分配的内存区间的起始虚地址。
free(addr): 释放由malloc()或calloc()所分配的起始虚地址为addr的内存区间

3. 管理物理内存页框的数据结构?内存管理区zone结构,伙伴系统?了解分区页框分配器分配页框的过程。

◆页框描述符
◆伙伴算法把空闲页框组织成11个链表
页框描述符 P174

struct page {
    unsigned long flags; /*页框状态标志P175*/
    atomic_t _count; /*页框的引用计数*/
    atomic_t _mapcount; /*对应的页表项数目*/
    unsigned long private; /*空闲时由伙伴系统使用*/
    struct address_space *mapping;用于页高速缓存
    pgoff_t index; 在页高速缓存中以页为单位偏移
    struct list_head lru; 链入活动页框链表或非活动..
    void *virtual; /*页框所映射的内核虚地址*/
}; P171

内存的3个管理区
◼ Linux把内存划分为3个管理区(zone)。
◼ ZONE_DMA:包含低于16MB的常规内存页框。用于对老式的基于ISA设备的DMA支持。
◼ ZONE_NORMAL:包含高于16MB且低于896MB的常规内存页框。
◼ ZONE_HIGHMEM:包含从896MB开始的高端物理页框。内核不能直接访问这部分页框。在64位体系结构上,该区总是空的。
内存的3个管理区
◼ ZONE_DMA+ZONE_NORMAL属于直接映射区
◼ 虚拟地址=3G+物理地址 或 物理地址=虚拟地址-3G,从该区域分配内存不会触发页表操作来建立映射关系。
◼ ZONE_HIGHMEM属于动态映射区
◼ 128MB虚拟地址空间可以动态映射到 (X-896) MB(其中X为物理内存大小)的物理内存,从该区域分配内存需要更新页表来建立映射关系。
◼ 直接映射区
◼ 是为了保证能够申请到物理地址上连续的内存区域。
◼ 动态映射区
◼ 会产生内存碎片,导致系统启动一段时间后,想要成功申请到大量的连续的物理内存,非常困难。
◼ 但是动态映射区带来了很高的灵活性(比如动态建立映射,缺页时才去加载物理页)。
内存管理区的结构 P176

struct zone { 
    unsigned long free_pages; 空闲页框数
    struct per_cpu_pageset pageset[NR_CPUS];
    /*每CPU页框高速缓存,为每个CPU预先分配了一
    些页框,以满足CPU对单个页框的请求*/
    struct free_area free_area[11]; 
    /*伙伴系统中的11个空闲页框链表*/
    struct list_head active_list; /*活动页框链表,存
    放最近正被访问的页框*/
    struct list_head inactive_list; /*非活动页框链表,
    存放最近未被访问的页框,便于回收页框*/
…….};

伙伴系统
◼ 假设要请求一个具有8个连续页框的块,该算法先在8个连续页框块的链表中检查是否有,如果没有,就在16个连续页框块的链表中找,如果找到,就把这16个连续页框分成两等份,一份用来满足请求,另一份插入到具有8个连续页框块的链表中;如果在16个连续页框块的链表中没有找到,就在更大的块链表中查找。直到找到为止。
image.png
页框分配器
◼ 负责处理对连续物理页框的分配请求。
◼ 伙伴算法把空闲页框组织成11个链表,分别链有大小为1,2,4,8,16,32,64,128,256,512和1024个连续页框的块。

4. 理解slab分配器的原理。slab分配器的作用?

◆只有几十或几百个字节的小内存区分配内存
slab管理
◼ 伙伴系统以页框为单位,适合于对大块内存的分配请求。
◼ slab分配器为只有几十或几百个字节的小内存区分配内存。如,file对象。
slab分配器
◼ 从页框分配器获得几组连续空闲页框。
◼ slab分配器为不同类型的对象生成不同的高速缓存,每个高速缓存存储相同类型的对象。高速缓存由一连串的slab构成,每个slab包含了若干个同类型的对象。
image.png
slab分配方法
◼ slab状态:
◼ 1)满:slab中的所有对象标记为使用
◼ 2)空:slab中的所有对象标记为空闲
◼ 3)部分:slab中的对象部分标记为空闲,部分标记为使用
◼ slab分配器首先从部分空闲的slab开始分配,如没有则从空的slab进行分配,如没有空slab则从连续物理块上分配新的slab,并把它赋给一个cache,然后再从新slab里分配空间。

5. 进程页表建立的时机?了解页目录表项或页表项所包含的字段。逻辑地址的划分,利用两级页表实现地址转换的过程。

◆3个域:页目录索引、页表索引和页内偏移
地址转换
◼ 32位处理机普遍采用二级页表模式,为每个进程分配一个页目录表,页表一直推迟到访问页时才建立,以节约内存。
◼ 虚地址分成3个域:页目录索引(前10位)、页表索引(中10位)和页内偏移(后12位)。
◼ 页目录项和页表项的数据结构相同。
image.png
表8.4 页表项所包含的字段
image.png

6. 请求调页。所缺的页可能存放的地方。

请求调页
◼ 请求调页增加了系统中的空闲页框数。
◼ 页面置换策略是LFU(Least Frequently Used)
所缺页的存放处
◼ 该页从未被进程访问过,且没有相应的内存映射。
◼ 该页已被进程访问过,但其内容被临时保存到磁盘交换区上。
◼ 该页在非活动页框链表中。
◼ 该页正在由其它进程进行I/O传输过程中。

7. 了解盘交换区空间的管理方法。

◼ 每个盘交换区都由一组4KB的页槽组成。
◼ 盘交换区的第一个页槽用来存放该交换区的有关信息,有相应的描述符。
◼ 存放在磁盘分区中的交换区只有一个子区,存放在普通文件中的交换区可能有多个子区,原因是磁盘上的文件不要求连续存放。
◼ 内核尽力把换出的页存放在相邻的页槽中,减少访问交换区时磁盘的寻道时间。

大纲问题回答

1. 进程地址空间的划分?管理进程私有地址空间的数据结构?链接虚拟内存区域的单链表和红黑树。指向映射文件对象的指针字段?指向进程页目录表的指针字段?(5)

进程地址空间的管理
32位机,每个进程的地址空间为4GB。进程的私有地址空间是前3G,进程的公有地址空间是后1G的内核虚空间
◼ 内核1GB虚空间中的前896MB用来映射物理内存的前896MB,因此前896MB的内存物理地址等于内核虚地址减去0xc0000000。后128MB的虚空间实现对超过896MB的物理内存的映射。
◼ 借助128MB高端内存地址空间可以访问所有物理内存。
◼ 基本思想:借一段地址空间,建立临时地址映射,用完后释放,达到这段地址空间可以循环使用,访问所有物理内存。
image.png

地址空间的各个虚拟内存区域是采用单链表和红黑树相组合的方式进行管理的

虚拟内存区域
管理进程私有地址空间的数据结构:虚拟内存区域描述符vm_area_struct
◼ 需用一组虚拟内存区域描述符vm_area_struct来描述进程地址空间的使用情况。
◼ 类似于Windows的虚拟地址描述符VAD

struct vm_area_struct {
    struct mm_struct * vm_mm; 虚拟内存描述符
    unsigned long vm_start; /*起始地址*/
    unsigned long vm_end; /*结束地址*/
    struct vm_area_struct *vm_next; /*单链表*/
    struct rb_node vm_rb; /*红-黑树*/
    struct file * vm_file; 映射文件时指向文件对象
    ……
}

struct file * vm_file; 映射文件时指向文件对象
虚拟内存描述符的数据结构类型

struct mm_struct { 
    struct vm_area_struct *mmap; 
    struct rb_root mm_rb; /*指向红-黑树的根*/
    pgd_t *pgd; /*指向页目录表*/
    atomic_t mm_users; /*次使用计数器*/
    atomic_t mm_count; /*主使用计数器*/
    struct list_head mmlist; 双向链表
    unsigned long start_code, end_code; /*可执行代码所占用的地址区间*/
……};

pgd_t pgd; /指向页目录表(page directory)*/

红黑树
◼ 红黑树是一棵排好序的平衡二叉树。
◼ 必须满足四条规则:①树中的每个节点或为红或为黑;②树的根节点必须为黑;③红节点的孩子必须为黑;④从一个节点到后代诸叶子节点的每条路径,都包含相同数量的黑节点,在统计黑节点个数时,空指针也算作黑节点。
◼ 这四条规则保证:具有n个节点的红黑树,其高度至多为2*log(n+1)。
新插入的节点一定是红色的叶子节点
单链表+红黑树
◼ 当插入或删除一个虚拟内存区域时,
◼ 内核通过红黑树搜索其相邻节点,并用搜索结果快速更新单链表。
◼ 红黑树用来快速确定含有指定地址的虚拟内存区域。
◼ 单链表用来扫描整个虚拟内存区域集合。

2. Linux堆的管理:malloc( ),free( )。

malloc(size): 请求size字节的内存。成功时,返回分配的内存区间的起始虚地址。
free(addr): 释放由malloc()或calloc()所分配的起始虚地址为addr的内存区间

3. 管理物理内存页框的数据结构?内存管理区zone结构,伙伴系统?了解分区页框分配器分配页框的过程。(5)

(1)页框描述符 P174

struct page {
    unsigned long flags; /*页框状态标志P175*/
    atomic_t _count; /*页框的引用计数*/
    atomic_t _mapcount; /*对应的页表项数目*/
    unsigned long private; /*空闲时由伙伴系统使用*/
    struct address_space *mapping;用于页高速缓存
    pgoff_t index; 在页高速缓存中以页为单位偏移
    struct list_head lru; 链入活动页框链表或非活动..
    void *virtual; /*页框所映射的内核虚地址*/
}; P171

(2)内存的3个管理区
◼ Linux把内存划分为3个管理区(zone)。
◼ ZONE_DMA:包含低于16MB的常规内存页框。用于对老式的基于ISA设备的DMA支持。
◼ ZONE_NORMAL:包含高于16MB且低于896MB的常规内存页框。
◼ ZONE_HIGHMEM:包含从896MB开始的高端物理页框。内核不能直接访问这部分页框。在64位体系结构上,该区总是空的
内存的3个管理区
◼ ZONE_DMA+ZONE_NORMAL属于直接映射区
◼ 虚拟地址=3G+物理地址 或 物理地址=虚拟地址-3G,从该区域分配内存不会触发页表操作来建立映射关系。
◼ ZONE_HIGHMEM属于动态映射区
◼ 128MB虚拟地址空间可以动态映射到 (X-896) MB(其中X为物理内存大小)的物理内存,从该区域分配内存需要更新页表来建立映射关系。
◼ 直接映射区
◼ 是为了保证能够申请到物理地址上连续的内存区域。
◼ 动态映射区
◼ 会产生内存碎片,导致系统启动一段时间后,想要成功申请到大量的连续的物理内存,非常困难。
◼ 但是动态映射区带来了很高的灵活性(比如动态建立映射,缺页时才去加载物理页)。
内存管理区的结构 P176

struct zone { 
unsigned long free_pages; 空闲页框数
struct per_cpu_pageset pageset[NR_CPUS];
/*每CPU页框高速缓存,为每个CPU预先分配了一
些页框,以满足CPU对单个页框的请求*/
struct free_area free_area[11]; 
/*伙伴系统中的11个空闲页框链表*/
struct list_head active_list; /*活动页框链表,存
放最近正被访问的页框*/
struct list_head inactive_list; /*非活动页框链表,
存放最近未被访问的页框,便于回收页框*/
…….};

(3)伙伴系统
管理连续的空闲内存页框,以解决外碎片问题。伙伴系统以页框为单位,适合于对大块内存的分配请求
◼ 假设要请求一个具有8个连续页框的块,该算法先在8个连续页框块的链表中检查是否有,如果没有,就在16个连续页框块的链表中找,如果找到,就把这16个连续页框分成两等份,一份用来满足请求,另一份插入到具有8个连续页框块的链表中;如果在16个连续页框块的链表中没有找到,就在更大的块链表中查找。直到找到为止。
image.png
伙伴算法把空闲页框组织成11个链表,分别链有大小为1,2,4,8,16,32,64,128,256,512和1024个连续页框的块
(4)页框分配器
◼ 负责处理对连续物理页框的分配请求。管理区分配器负责搜索一个能满足动态内存请求的内存管理区。当空闲页框不足时,管理区分配器应当触发页框回收算法。 在每个管理区内的页框,除了一小部分页框被保留为每 CPU 页框高速缓存外(以满足本地 CPU 发出的对单个页框的请求),其它的由伙伴系统来管理。

4. 理解slab分配器的原理。slab分配器的作用?(5)

◆只有几十或几百个字节的小内存区分配内存
slab管理
◼ 伙伴系统以页框为单位,适合于对大块内存的分配请求。
◼** slab分配器为只有几十或几百个字节的小内存区分配内存。如,file对象slab分配器把小内存区看作对象,slab分配器对不再引用的对象只是释放但内容保留,以后再请求新对象时,就可直接使用而不需要重新初始化
原理:获得连续页框,为不同类型对象生成不同的高速缓存放在页框里,形成每CPU 页框高速缓存;
作用:为只有几十或几百 B 的内存区分配内存;**
slab分配器
◼ 从页框分配器获得几组连续空闲页框。
slab分配器为不同类型的对象生成不同的高速缓存,每个高速缓存存储相同类型的对象。高速缓存由一连串的slab构成,每个slab包含了若干个同类型的对象
image.png
slab分配方法
◼ slab状态:
◼ 1)满:slab中的所有对象标记为使用
◼ 2)空:slab中的所有对象标记为空闲
◼ 3)部分:slab中的对象部分标记为空闲,部分标记为使用
◼ slab分配器首先从部分空闲的slab开始分配,如没有则从空的slab进行分配,如没有空slab则从连续物理块上分配新的slab,并把它赋给一个cache,然后再从新slab里分配空间。

5. 进程页表建立的时机?了解页目录表项或页表项所包含的字段。逻辑地址的划分,利用两级页表实现地址转换的过程。(3)

◆3个域:页目录索引、页表索引和页内偏移
地址转换
◼ 32位处理机普遍采用二级页表模式,为每个进程分配一个页目录表,页表一直推迟到访问页时才建立,以节约内存。
虚地址分成3个域:页目录索引(前10位)、页表索引(中10位)和页内偏移(后12位)
Linux系统的页目录项和页表项的数据结构相同。页表项所包含的字段:
Present标志:为1,表示页(或页表)在内存;为0,则不在内存。
页框物理地址(20位):页框大小为4096,占去12位。20+12=32。
Accessed 标志:页框访问标志,为1表示访问过。
Dirty标志:每当对一个页框进行写操作时就设置这个标志
转换过程即先由页目录索引得到页目录表对应位置,之后再得到对应页表始址,由页表索引得到页的对应始址;最后利用页内偏移与页的对应始址计算得到物理地址
◼ 页目录项和页表项的数据结构相同。
image.png
表8.4 页表项所包含的字段
image.png

6. 请求调页。所缺的页可能存放的地方。(1)

请求调页
◼ 请求调页增加了系统中的空闲页框数。
最少使用页面置换策略LFU(Least Frequently Used)
所缺页的存放处
◼ 该页从未被进程访问过,且没有相应的内存映射。
◼ 该页已被进程访问过,但其内容被临时保存到磁盘交换区上。
◼ 该页在非活动页框链表中。
◼ 该页正在由其它进程进行I/O传输过程中

7. 了解盘交换区空间的管理方法。

◼ 每个盘交换区都由一组4KB的页槽组成。
◼ 盘交换区的第一个页槽用来存放该交换区的有关信息,有相应的描述符。
◼ 存放在磁盘分区中的交换区只有一个子区,存放在普通文件中的交换区可能有多个子区,原因是磁盘上的文件不要求连续存放。
◼ 内核尽力把换出的页存放在相邻的页槽中,减少访问交换区时磁盘的寻道时间。