lec 07 操作系统管理页表映射
0 Contents
1 操作系统设置页表映射
何时设置页表映射?
-
操作系统自己使用的页表
-- 在启动时填写
-- 映射全部物理内存- 虚拟地址 = 物理地址 + 固定偏移(直接映射,Direct Mapping)
- 思考:为什么需要直接映射?
-
应用进程的页表
-- 何时设置?
2 立即映射
- 创建进程时,OS按照虚拟内存区域填写进程页表
-- 例如,代码段和数据段
-- 具体步骤:- 步骤-1: 分配物理页(alloc_page)
- 步骤-2: 把应用代码/数据从磁盘加载到物理页中
- 步骤-3: 添加虚拟页到物理页的映射(add_mapping)
- 步骤-4: 未加载完毕,回到步骤-1
分配物理页的简单实现
操作系统用位图记录物理页是否空闲
0:空闲;1:已分配
OS填写页表基地址
结构体保存页表的基地址
填写进程页表
!直接映射弊端
-
立即映射是一种操作系统可以选择的页表填写策略
-- 在初始化进程虚拟地址空间时,直接在进程页表中添加各虚拟内存区域的映射 -
潜在弊端
-- 以关卡/副本类型游戏加载为例:只玩1关,加载1000关- 物理内存资源浪费
- 非必要时延
3 延迟映射
想法
-
解决立即映射弊端的直观想法
-- 操作系统按进程实际需要分配物理页和填写页表,避免分配的物理页实际不被用到的情况 -
主要思路:解耦虚拟内存分配与物理内存分配
-- 先记录下为进程分配的虚拟内存区域
-- 当进程实际访问某个虚拟页时,CPU 会触发缺页异常
-- 操作系统在缺页异常处理函数中添加映射
操作系统需要区分合法/非法缺页异常
执行以下代码,操作系统可以发现segmentation fault
。
#include<stdio.h>int main()
{char *p = NULL;printf("%s\n",p);return 0;
}
操作系统记录为进程分配的虚拟内存区域
- 虚拟地址空间
-- 若干非连续的虚拟内存区域- 每个虚拟内存中虚拟地址都是进程可用的,具有相同的访问权限。
- 例如:代码,数据,堆,栈
- 访问非法虚拟地址会触发CPU异常,操作系统将会跑出segmentation fault。
合法虚拟地址信息的记录方式
- 记录进程已经分配的虚拟内存区域
-- Linux: 对应结构体vm_area_struct
,位于linux/include/linux/mm_types.h
内定义。
(有意思的是,虚拟内存在linux内出现是在2008年)。
-- Chcore: 对应以下的结构体。
VMA 添加方式
1.OS创建进程时分配
- 数据(对应ELF文件的数据段)
- 代码(对应ELF文件的代码段)
- 栈(初始没有内容)
2.进程运行时添加
- 堆,栈
- mmap/munmap
-- 分配内存buffer和加载新的代码库
mmap: 分配一段虚拟内存区域
- 通常用于把一个文件或一部分映射到内存
- 也可以不映射任何文件,仅仅新建虚拟内存区域(匿名映射)
linux:
示例
执行mmap后,vma发生变化
mmap 映射文件
VMA如何添加
- 途径2: 进程运行时添加/应用程序主动向OS发起系统调用
-- mmap()- 申请空的虚拟内存区域
- 申请映射文件数据的虚拟内存区域
-- brk():扩大、缩小堆区域
-- 栈VMA的可选策略 - OS为进程初始分配固定大小的栈VMA,在发现stackoverflow之后自动扩大栈VMA
-- 用户态的malloc(API)也可能改变VMA - 调用brk,在堆中分配新的内存
- 调用mmap分配较大区域
VMA判断缺页异常的合法性
-
缺页异常(page fault)
-- AARCH64:触发(通用的)同步异常(8)
-- 根据ESR信息判断是否为缺页异常
-- 访问的虚拟地址存放在FAR_EL1 -
操作系统的缺页处理函数
-- FAR_EL1中的值不落在VMA区域内,则为非法
-- 反之,则分配物理页,并在页表中添加映射
延迟映射与立即映射对比
- 优势:节约内存资源
- 劣势:却页异常导致访问延迟增加
- tradeoff:
-- 应用程序具有时空局部性
-- 缺页异常处理中采用预先映射策略。节约内存并且减少缺页异常次数。
OS向应用提供灵活的内存管理系统调用
4 虚拟内存的扩展功能
1.共享内存
节约内存与进程通信作用。
2.写时拷贝
实现:修改页表项权限,在缺页时拷贝,恢复。
fork:节约物理内存,性能加速。
3.内存去重
- memory deduplication
-- 基于写时拷贝机制
-- 在内存中扫描,发现具有相同内容的物理页面
-- 执行去重
-- 操作系统发起,对用户态透明
4.内存压缩
- 基本思想
-- 当内存资源不充足的时候, 选择将一些“最近不太会使用”的内存页进行数据压缩,从而释放出空闲内存
大页的利弊
- 好处
-- 减少TLB缓存项的使用,提高 TLB 命中率
-- 减少页表的级数,提升遍历页表的效率 - 案例
-- 提供API允许应用程序进行显示的大页分配
-- 透明大页(Transparent Huge Pages) 机制 - 弊端
-- 未使用整个大页而造成物理内存资源浪费
-- 增加管理内存的复杂度