哈工大操作系统-3-内存管理
本文最后更新于293 天前,其中的信息可能已经过时,如有错误请发送邮件到cishaxiatian@gmail.com

内存使用与分段

内存使用:将程序放到内存中,PC指向开始地址

20_1
20_2

原本内存中顺序常驻系统 –> 进程1 –> 进程三

  1. 进程一 睡眠先入磁盘
  2. 进程二 进入内存
  3. 进程三 睡眠换出
  4. 进程一 换入

也就是 实际内存中调用的地址是 动态基地址 + 偏移地址

  • 详情如下
20_3

编译后的内存基地址通过PCB进行记录,也就是说pcb在进程调度的时候,PCB内部存的基地址 ip 动态变化的

20_4

程序段结构

20_5

翻译:

  • 各个程序段 : 如数据段、代码段、栈段等都是独立的存在的 ,在内存中分布成块状
20_6

如上,每一个区域的起始地址在自己的内存区域都看作起始地址

20_7
  • LDT表中记录每个块中的初始地址
  • GDT表中也存入LDT表中的地址
  • 即可以通过GDT找到LDT表,进而确定指令在内存中的方位

内存分区与分页

首先明确一点,只要和进程有管的信息都放在PCB中,例如(LDT表)

21_1
  • 三个适配规则
21_2
21_3

比如上述的 mov [0x2240],%eax

  1. 2240除以4K ,也就是左移3位(这里为16进制,所以为三位即可),计算得出页号
  2. 随后通过PCB中的页表指针找出页号对应的页框号,随后用页框号 × 12bit 得到实际的物理地址

多级页表与快表

22_1

如何找到地址:

根据 逻辑页号 找到 页框号

22_2
22_3

解释:

这里为两个进程算

每个进程都有自己的 页目录表 + 页表 这里引出两个进程,也就是4K + 4K = 8K,又因为两个进程,所以攻占用16K的内存空间



多级页表增加了访存的次数,尤其是64位系统

22_4

TLB -> 快表,是一个reg用来快速找到 页框号 ,确定物理页号,有些像cache,如果TLB中没有查到需要的页号,则还是去多级页表中查找,找到了就放入TLB 中,下次就无需去多级页表中查找

说白了就是用一个缓冲区作为 加速器

22_5
/************

有效访问时间 先是查TLB表(查表就要访存,所以加上一次TLB的访存时间),后面是没有命中的时候,先是TLB的访存时间MA,随后还要访问多级页表中的访存时间MA,所以是2MA

************/

注意后面:

TLB的是寄存器reg价格贵,但是TLB越大带来的效果就越强,命中率就会拉高,此时我们通过多级页表就会少,提高程序的效率!!!

需要 妥协 平衡 折中

22_6

段页结合的实际内存管理

23_1

先分段再分页,用户面向虚拟地址,虚拟地址翻译之后的对用户是透明的(看不见),计算机是对分页操作的

23_2

先是 逻辑地址 –> 虚拟地址 –> 通过页号和偏移找到的实际的页框号 –> 再找出物理地址

例子 : jmp 40

则对应物理地址就是1040, 即再最后的物理地址的时候 基地址才加上偏移的 40

一个实际的段、页式内存管理

23_3
23_4
  1. 首先是在 虚拟内存 中选出一段内存载入
  2. 建立虚拟地址内存的表
  3. 把刚刚载入的段进行分页
  4. 建立LDT表进行索引(实际的物理地址)
23_5
  • copy_mem 分配虚存、建段表
  1. p : PCB 管理进程的数据结构
  2. ldt : 与pcb进程相关联
  3. nr : task数组的索引,即第几个进程
  4. new_data_base : 基址
23_6

每个进程需要又自己的页表和段表,页表可以不用切换,因为互不重叠

但是在实际的系统的是很有可能重叠的

23_7

这里是子进程的创建:

  • 父进程 和 子进程 公用一片内存
23_8

上图主要得到目录项的编号

为什么要 >>20 而不是 >>22呢

答案 : 先是>>22取得页目录号,但是一个页目录号是占 4byte ,所以还要乘4( <>20 而不是 >>22

23_9

给子进程分配内存,原先子进程的页表是空的,不进行分配,不占用内存资源,需要时在进行分配

get_free_page : 分配内存空间的函数,作用是找到内存中是 0 的一项(寻找内存中空白的 地方好用来分配)

  • 此时页目录已经创建完毕
23_10

将子进程和父进程指向同一个页表(此时进程共享)

  1. *from_page_table :是父进程的页地址
  2. this_page : 用this_page给子进程的to_page_table赋值,且该变量能进行只读锁定
  3. mem_map : 自加,如果父进程结束,内存也不能释放,子进程还需要使用
23_11

上图易于理解

23_12

总结上图 :



  • 进程中的 p = 0x300 指的是虚拟内存地址,而物理内存的地址如 0x00400300 则是实际的存储地址。

  • fork() 创建一个子进程。此时,子进程会复制父进程的虚拟地址空间,但不会立即复制物理内存中的数据

    父子进程在 fork() 后共享相同的物理内存地址(如图中 0x00007300 位置)。

写时复制机制

  • 当子进程或父进程试图修改共享内存中的数据时,操作系统会触发写时复制。
  • 如图所示,当子进程修改 p 指向的内存(将值 7 改为 8)时,系统会先将共享的物理内存数据复制到新地址(如 0x00008300),然后子进程修改这个新地址中的数据
  • 修改后的父子进程内存地址将不再共享,避免相互影响。

上半部分表示父进程的内存状态:*p = 7 表示 p 指向的内存地址中存储的值为 7,物理内存地址为 0x00007300

fork() 后,下半部分是子进程的状态:子进程 p 指向的内存地址中值被修改为 8,此时写时复制发生,子进程获取了新的物理内存地址 0x00008300,父进程继续保持原地址不变。

内存换入-请求调页

24_1

请求的时候再映射!!! 说白了就是一段内存复用

24_2
24_3
  1. 是MMU硬件执行的,人为干预不了,但是人为可以干预内核中的操作
  2. 系统发现缺页,去中断表中查询缺页中断号,进入中断进行补页
  3. 找到磁盘中程序需要使用的页
  4. 载入到物理内存
  5. cpu重新从虚拟内存中读取指令,虚拟内存 从 物理内存中调用
  6. 以上完全就是一个中断处理函数,所以当cpu执行中断的时候,PC值在自动的情况下会 PC++ ,但是!!!这里系统会自动不让其PC + 1,还是从缺页的地址开始执行。

用户:卡了一下,但是并不知道系统的后台调用页

24_4

复习一下:

idt : 中断向量表,初始化idt形成向量中断对应号以及相对应的中断执行函数

24_5
  • 左边:
  1. 先是一堆压栈进行现场的保护
  2. movl $0x10, %edx 进入内核栈的选择子
  3. 利用 cr2 来保存 页错误线性地址(虚拟地址)


  • 右边
  1. pushl %eax 后面call _do_no_page ,这两句就是调用c语言,进行传入错误页的参数
24_6

address&=0xfffff000; 与操作得到页面地址(即后12位)

  • bread_page: (block_read_page) 去磁盘上读
  1. 读取的数据给page(刚刚的缺页地方)
  2. executable 进程所对应的可执行文件

put_page : 建立物理页和虚拟页之间的映射

24_7
  1. 根据 address 找到 页目录项
  2. 根据 页目录项 找到页表项
  3. 根据 页表项 和 刚刚找到的 page内存 进行映射

内存换出

引言

25_1
25_2

ABCD 进程没有一个执行完毕,导致不停的打断(缺页)

25_3

方法规则是 : 预测下一个进程,换掉不在运行队列的进程,就是”最优”。

问题 : 怎么预测是个问题!

25_4

LRU的准确实现—时间戳

25_5

每一次都要查看时间戳,每次换页的时候都要改变数字,时间戳越来越大,很有可能发生溢出

LRU的准确实现—页码栈

25_6

CLOCK算法 — 丐版

25_7

CLOCK算法 — 豪华版

25_8

如上图:

问题所在:如果程序在莫一个时间段中缺页次数非常少,此时CLOCK中的R将会逐渐变为1,如果突然缺页,则需要转一圈(很慢的速度)才能进行缺页更换

有两个指针进行监测

  • 用来清除R位,移动速度要快!
  • 用来选择淘汰页,移动速度慢!



25_9

总结

25_10
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇