笔记大纲
- 内存分页技术
- 简单分页、多级页表
- Linux的内存管理技术
1. 内存分页技术
大部分虚拟内存使用一种称之为分页的技术,虚拟地址空间按照一定大小被分成若干个页或称之为页面。页面大小一般为512字节的整数倍
1.1 缺页
当操作系统读取DRAM缓存页时,如果虚拟页不在内存中,则发生缺页中断异常,操作系统需要通过内存调页技术进行页面换入从而实现虚拟内存页的读取。
1.2 局部性原理
按照常理理解,虚拟内存技术在物理内存不足时频繁发生缺页中断,导致交换分区极度活跃,效率肯定不高,但是操作系统设计者提出了局部性原理的概念来优化这个问题。局部性原理包括时间局部性和空间局部性,在虚拟内存域,空间局部性是指程序趋向于在一个较小的活动页面集合上工作,这个集合叫做工作集或者叫常驻集合,在初始阶段,操作系统将工作集调入内存,在接下来的程序运行阶段工作集的页将被频繁命中。
1.2.1 内存抖动
抖动这个概念是指,当DRAM内存负载较高,但是进程在频繁调度,进程所使用的的虚拟页面频繁未命中,操作系统频繁陷入缺页中断,频繁和磁盘交换页面,导致操作系统性能急速下降。Linux操作系统可以用thrashing函数监控缺页中断的次数和缺页数量。
1.3 页表
虚拟内存系统必须有某种方法来确定一个虚拟页是否在内存之中,如果存在还需要确定这个虚拟页存放在哪个物理地址/物理帧,如果不在,系统还需知道虚拟页存放在磁盘哪个位置,那么操作系统怎么实现呢?答案是这个功能由软硬件结合来解决,MMU和页表共同来维护实现。
虚拟地址被分为虚拟页号(高位)和偏移量(地位),虚拟页号作为页表的索引,从而找到该虚拟页面对应的页表项。
1.3.1 转换检测缓冲区 TLB
如果每次CPU产生一个虚拟地址,MMU就必须检索一个虚拟和物理的映射关系,那么性能肯定是有所影响的。操作系统设计者在为了优化这个问题,在MMU中写入了一个页表缓存,称为翻译后备缓冲区/转换检测缓冲区 TBL,以加快虚拟内存和物理内存的翻译过程。
1. CPU产生一个虚拟地址
1. MMU从TLB中取出相应的虚拟地址缓存
1. MMU将虚拟地址翻译成物理地址,并通过总线发送到主存
1.3.2 大内存分页
1.1.2.1 多级页表
简单分页因为进程的页表需要消耗内存空间,对于64位操作系统来说,如果用简单分页那么光页表的内存消耗都是惊人的,那么操作系统设计者提出了
多级页表的策略来优化大内存的分页问题。其实多级页表和普通分页核心思想没变,只不过将页表不是按照一维的形式展示,而是将页表进行类似于构建索引一样进行树化,一级页表包含1024个二级页表,二级页表再分为1024个页表项的方式进行优化,其本质还是没有多大变化。
1.1.2.2 倒排页表
- 节省空间
- 虚拟地址转换物理地址困难
2. 页面置换算法(简介,后续专门专题整理 TODO)
3.4.1 最优页面置换算法
理论存在,实现困难
3.4.2 先进先出置换算法 FIFO
可能会抛弃重要页面
3.4.3 最近最少使用算法 LRU
表现优秀、实现困难
3.4.4 最近未使用置换算法 NFU
近似LRU效果
3.4.5 第二次机会页面置换算法
性能相比FIFO略好
3.4.6 时钟页面置换算法
主流系统的实现
3.4.7 工作集/工作集时钟 置换算法
耗时开销很大、算法优秀
3.Linux内存管理
Linux内存管理是分段和分页结合实现,这主要是上面 Intel 处理器发展历史导致的,因为 Intel X86 CPU 一律对程序中使用的地址先进行段式映射,然后才能进行页式映射。既然 CPU 的硬件结构是这样,Linux 内核也只好服从 Intel 的选择。
3.1 分段 + 分页
逻辑地址:程序所使用的地址,通常是没被段式内存管理映射的地址,称为逻辑地址;
线性地址:通过段式内存管理映射的地址,称为线性地址,也叫虚拟地址;
3.2 X86处理器对虚拟内存的支持
x86处理器的虚拟内存和MULTICS操作系统(麻省理工的一个研究项目)相似,既有分段机制也有分页机制,但是从x86-64处理器开始,分段机制已经认为过时,不再提供支持,但是x86-64处理器在本机模式下仍然有一定的分段支持,但是也只是为了兼容而已,并不是真正意义上的支持。
3.2.1 X86虚拟内存 - LDT 局部性描述符表
每一个进程都有专属自己的LDT,LDT表包括描述了进程的代码、数据、堆栈等信息。
3.2.2 X86虚拟内存 - GDT 全局描述符表
操作系统中所有的进程共享一个全局的描述符表,GDT描述了操作系统段信息、和系统信息。