页表、物理地址、逻辑地址、页面置换算法
页表:
虚拟内存的概念。操作系统虚拟内存到物理内存的映射,被称为页表。
不可能每一个虚拟内存的Byte都对应到物理内存的地址,因为这样的页表非常大,于是引入 页(Page)概念,进行分页,减小虚拟内存页对应物理内存页映射表的大小。
缺页异常:malloc和mmap函数分配内存是仅建立了 进程虚拟地址空间,并没有分配虚拟内存对应的物理内存,进程访问没有建立映射关系的虚拟内存时,处理器自动触发 缺页异常,引发缺页中断。
缺页中断:缺页异常后产生一个缺页中断,操作系统根据页表中的 外存地址 在外村中找到所缺的一页,将其调入 内存。
在进行动态内存分配的时,(C++ 中 new),操作系统会在硬盘中创建或申请一段虚拟内存空间,并更新到页表(分配一个页表条目),该条目指向硬盘上新创建的虚拟页,产生映射关系。
逻辑地址转线性地址:段起始地址(基地址) + 段内偏移地址 = 线性地址
例如一个存储器大小是 1KB(8位)可以分为4段,第一段地址范围是0~255,段地址为0;;;第四段地址范围是768~1023,段地址为768;偏移地址为0~255之间。
线性地址是一个32位的无符号整数,可以用来表达4GB的地址,高达4294967296个内存单元。十六进制表示(0x00000000~0xffffffff)
分页机制:
4KB分页大小,线性地址的高10位为页目录项在页表中的编号,中间10位为页表中的页号,低12位是偏移地址。
4MB分页大小,高10位页号,低22位偏移地址。
线性地址转物理地址:页目录地址 + 页目录索引 = 页表地址 ----- 页表地址 + 页表索引 = 页地址 ------ 页地址 + 页内偏移 = 物理地址
页表计算:
例:若页面大小L为1K(1024)字节,页号2对应的内存块号b=8,将逻辑地址A=2500转换为物理地址E。 等价描述:某系统按字节寻址,逻辑地址结构中,页内偏移量占10位(说明一个页面的大小为2^10B = 1KB),页号2对应的内存块号 b=8,将逻辑地址A=2500转换为物理地址E。
①计算页号、页内偏移量 页号P=A/L = 2500/1024 = 2; 页内偏移量W= A%L = 2500%1024 = 452
②根据题中条件可知,页号2没有越界,其存放的内存块号b=8
③物理地址E=b*L+W=8 * 1024+ 425 = 8644
在分页存储管理(页式管理)的系统中,只要确定了每个页面的大小,逻辑地址结构就确定了。因此,页式管理中地址是一维的。即,只要给出一个逻辑地址,系统就可以自动地算出页号、页内偏移量两个部分,并不需要显式地告诉系统这个逻辑地址中,页内偏移量占多少位。
页面置换算法:
1.最佳置换法(OPT,Optimal): 性能好但无法实现
🔴每次选择淘汰的页面将是以后永不使用,或者在最长时间内不再被访问的页面,这样可以保证最低的缺页率。
2.最近最久未使用置换算法(LRU):性能好但需要硬件支持,实现困难
🔴 LRU(Least recently used):每次淘汰的页面是最近最久未使用的页面;
实现:赋予每个页面对应的页表项中,用访问字段记录该页面自上次被访问以来所经历的时间t (需要硬件支持(寄存器、栈),性能好但实现困难,开销大)
当需要淘汰一个页面时,选择现有页面t 值最大的,即最近最久未使用的页面。
3.先进先出置换算法(FIFO):简单、效率低
🔴 每次选择淘汰的页面是最早进入内存的页面。
🔴 Belady异常一:当为进程分配的物理块数增大时,缺页次数不减反增的异常现象。
只有FIFO算法会产生Belady异常,且先进入的页面也有可能经常被访问,算法性能差。
4.时钟置换算法(CLOCK)或最近未使用算法(NRU,Not Recently Used):
🔴 循环扫描缓冲区像时钟一样转动;
简单实现:为每个页面设置一个访问位,再将内存中的页面都通过链接指针链接成一个循环队列,当某页被访问时,访问位 置为 1;
当需要淘汰一个页面时,只需要检查页的访问位,如果为 0,就选择将该页换出;如果是1,将其置为0,暂不换出,检查下一个页面;
若第一轮扫描完全是1,则将这些页面的访问位依次置为0后,在进行第二轮扫描 - 选择一个淘汰页面最多会经过两轮扫描;
5.改进型的时钟置换算法:
🔴 如果淘汰的页面没有被修改过,就不需要执行 I/O 操作写回外存,只有被淘汰的页面被修改过时,才需要写回外存;
🔴 因此除了考虑页面有无被访问,还应考虑有无被修改过,其他条件相同时,优先淘汰没有修改过的页面,避免 I/O操作, 修改位 = 0(没有被修改); = 1(被修改过)
🔴(访问位 Access,修改位 Modify);将所有可能被置换的页面排成一个循环队列;
🔴 一轮:找到第一个(A = 0,M = 0)替换;不修改任何标志位;
🔴 二轮:找到第一个(A = 0,M = 1)替换;同时将扫描过的访问位 A 置为 0;
🔴 三轮:找到第一个(A = 0,M = 0)替换;不修改标志位;
🔴 四轮:找到第一个(A = 0,M = 1)替换;
🔴 第二轮会将所有访问位置为 0 - 选择一个淘汰页面最多会进行四轮扫描;
算法规则 | 优缺点 | |
---|---|---|
OPT | 优先淘汰最长时间内不会被访问的页面 | 缺页率最小,性能最好,但无法实现 |
FIFO | 优先淘汰最先进入内存的页面 | 实现简单,性能差,可能出现Belady异常 |
LRU | 优先淘汰最近最久没访问的页面 | 性能很好;但需要硬件支持,算法开销大 |
CLOCK (NRU) | 循环扫描,第一轮淘汰访问位=0的,并将扫描过的页面访问位改为1。若第一轮没选中,则进行第二轮扫描。 | 算法开销小;但未考虑页面是否被修改 |
改进型CLOCK (改进型NRU) | 好! | 算法开销较小,性能也不错 |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)