- 内存管理:
- 对每个进程需要分配一定的内存空间,但是不同进程所需的大小不一样,并且进程会动态增加移除,操作系统需要对内存进行一定的管理(分配和回收)
- 连续分配内存四种方法
- 空闲区域使用链表形式连接起来
- 首次适应算法:从头遍历到的第一个可以使用空闲区域
- 最佳适应算法:遍历所有的空闲区域,找到可以使用的最小的空闲区域,可以把大块空闲区域留给内存较大的进程,但是会产生很多不可用的小碎片
- 最大适应算法:将剩下的空闲区域按照从大到小排序,每次使用空闲区域最大的
- 邻近适应算法:首次适应算法的更新版(低地址部分有很多小碎片),加了一个指针,每次不是从头遍历空闲区域
- 基本分页:
- 将一个进程的内存空间分为有限个页,每页大小都一样,进程需要一个页表,记录页号对应的内存块号,用来将逻辑地址(每个进程自己的页号)映射到物理地址(内存块号对应起始实际物理地址)。例如一个页大小4KB,4GB的内存有 2^32/2^12 = 2^20个内存块,页表中一条数据至少需要3B,一般用4B记录,那么一个内存块可以记录一个最多1024条数据的页表,逻辑地址组成(20位页号+12位页内偏移量)
- 快表可以缓存最近使用过的页号-内存块数据,加快寻址时间
- 当进程所需内存很大时,即页表需要用多个内存块存储,这雪内存块可以是离散的,需要用多级分页技术实现
- 多级页表逻辑地址(32位系统):10位一级页号+10位二级页号+12位页内偏移量(对应页大小为4KB);6位一级页号+8位二级页号+8位三级页号+10位页内偏移量(对应页大小为1KB)
- 基本分段:
- 程序根据自身的逻辑关系划分为若干个段(main函数段、某个子函数段、变量段),每个段的内存大小不一样,逻辑地址分为段号和段内地址(比如16位段号+16位段内偏移量),这样的划分一个段最多有64KB,一个进程最多有2^16个段
- 段表记录段号对应的段长和起始实际物理地址,每个段表项占用6B大小(16位段长+32位物理地址)
- 好处就是空间局部性增强,更容易实现信息的共享和保护
- 分页和分段对比:
- 分页是将内存分为相同大小的内存块,一个内存块是一页,进程需要切割成相应大小的页,并将页号-内存块号这样的映射关系用页表记录下来,其中页号是顺序增加的,不用显式记录
- 分段是将程序按照逻辑分为不同大小的代码段(对于16位段内偏移量,代码段大小不能超过64KB),代码段之间的存放是离散的,需要用二维的段表保存段号-段长(16位)-基址(32位),其中段号是顺序增加的,不用显式记录
- 段页式:
- 逻辑地址:16位段号+4位页号+12位页内偏移量(12位段号+2位一级页号+8位二级页号+10位页内偏移量)
- 分段这一步用户可见,16位段内偏移量会细分为页号和页内偏移量,用户不可见
- 段页表:段号-页表长度-页表存放内存块号