目录

操作系统中的内存管理:分段、分区、分页

操作系统中的内存管理:分段、分区、分页

内存要怎么用起来呢?存储程序的思想,把程序放入内存,程序在CPU中取指执行!

而用户程序有逻辑地址,实际的内存是物理地址,于是先有一个地址重定位的问题。

由于程序载入内存之后,睡眠了的话,还会被移入到磁盘,因此在运行时做重定位更好,这叫做地址翻译

程序编译好是不用做任何更改的,当要运行的时候,创建进程控制块PCB,这里面就有一个基址,再把PC置为初始地址,基址+逻辑地址=物理地址。

分段

把整个程序放进内存?

不,放入的是程序段、数据段等。

那么,现在的PCB要放每个段的基址,这就形成了一个段表

此时的寻址就是:段基址+段内偏移。

程序分成多个段,代码段、数据段,每个段在内存中找到空闲的地方,然后把基址记录在LDT中,LDT初始化之后就赋值给PCB,PC指针设置成初值,然后根据PC指针进行取指执行,在每次执行的时候,都查这个LDT表,根据表中的基址和程序中的地址,在这里找到物理地址,然后就可以使用起来内存了。

分区

对程序进行分段,但是怎么找到空闲的内存呢?

对内存进行分区,固定分区与可变分区,当一个段提出请求的时候,就根据首先匹配、最佳匹配、最差匹配等算法进行分配。

操作系统用空闲分区表和已分配分区表来管理内存资源。

但是分区总会造成内存碎片的问题。

分区是虚拟内存上的。

分页

把段请求打散行不行?这就把连续化为离散。

物理内存分页,每页比较小,最多浪费1页。

用户要分段,物理内存要分页。操作系统既支持段,又支持页。

这个时候的寻址呢?

每个进程得有自己的页表页号表示逻辑页,而页框号表示物理页。

于是,通过页号能找到物理页,通过页内偏移就找到物理地址了。

利用分区适配算法,在虚拟内存中找出一个空闲分区,放入,然后将段分,映射到物理地址。需要用段表记录虚拟内存区域的对应,用页表记录对应页所在物理地址。

快表

单独的分页还不行,因为页小了,页表就变大了。

  • 只放用到的页号行吗?但不连续的页号没法随机访问,查起来很慢。

  • 使用多级页表呢?就像增加目录一样,但每增加一级,就多了一次访存。

于是,我要是能记住最近访问的页就好了,快表就是用硬件根据页号一步找到页框号。那如果快表里面没有呢?就老老实实去多级页表找。

为什么快表可以?因为程序对地址的访问有局部性!(循环、顺序)

页的换入换出

为什么要换入换出?为了实现虚拟内存!

在用户眼里有4G空闲,实际却不是哦,也就是说用户眼里这样的大内存是换入换出实现的!

换入的核心:请求调页,没有这个页号,就赶紧去磁盘调页,需要中断机制。

换出的算法:FIFO、LRU。

swap 分区就是做这个事:换入、换出 = > 虚拟内存 = > 段页 = > 程序载入 => 进程

什么叫颠簸呢?不断地在磁盘和内存中换入换出,但CPU啥也执行不了。