目录
- 非连续内存的管理方式
- 分段机制
- 分页机制
- 页帧Frame
- 页Page
正文
非连续内存的管理方式
引言:连续内存分配的缺点:
1.分配给一个程序的物理地址是连续的
2.内存利用率低
3.有内碎片、外碎片问题
且不论何种适配方式,都不能完全杜绝碎片问题
引入非连续内存分配方法
非连续内存分配方法:解决碎片问题,同时令运行的程序能够有效地隔离和内存资源管理,还可以支持共享数据和代码,类似共享库。
潜在问题:管理开销本身
如何建立虚拟地址和物理地址之间的转化(软件方案/硬件方案)
软件方案:开销非常大
硬件方案:开销相对小,这里主要介绍分段和分页机制
分段机制
不同段之间有不同的属性,我们需要一个方法有效隔离这些不同的断的话,则有助于我们更好地去管理地址空间。
从应用程序的编写和运行来说, 他虚拟的逻辑地址空间是一个连续的地址空间。但是虽连续,通过分段后也可以有效的隔离开来。如图所示,可以把不同的数据、库、代码段等相应的分离出来。放在某一个特定的地址用一个特定的管理权限管理起来。分离出来后,可以相互共享或访问;也可以令一些数据相对隔离,部分只读部分读写。有效地进行管理分配,有效地实现保护机制。
左边是连续的虚拟地址,右边是不连续的物理地址,那么中间就需要一个映射机制来确定相互间的联系。
我们把执行程序运行的逻辑地址空间看作一个连续的一维线性数组,通过映射关系,将不同的内存块(数据、代码、堆、栈等)分别映射到不同的内存的段中。映射之后,他们大小不同,位置不同。这之间的关系就是通过段管理机制实现的。这种机制也可以用软件实现,但是开销会非常大,所以我们尽可能想要用硬件支持。
这里就需要怎么通过硬件机制来支持分段的寻址。
一个一维的逻辑地址其实是不同的段组成的,这个段可以不连续。那么首先,一维地址分成两块,一块是段的寻址和段内的偏移寻址。s和addr放在一起,就形成了以段机制来管理的寻址方式。如果段号s和addr是分开的,那么是段寄存器+地址寄存器实现方式,x86是典例。另一种是把段和段内偏移合在一起形成一个完整地址,没有段寄存器来把段的编号单独管理起来,这是单一地址管理方式。
从一维线性逻辑地址空间映射到不同的物理空间去,而这个物理空间是由不同的段组成的。
详细过程:
程序通过CPU执行某条指令。CPU就需要去寻址(找数据、代码在什么地方),那么OS会把这个逻辑地址分成两块(段号/段内偏移),通过段号希望找到所在物理内存的起始地址;段表会存着逻辑地址和物理地址之间的映射关系,又因为每一个段的大小不同,所以段表也会存这些信息,也就说段表会放段的起始地址和段的长度限制这两种信息。段表的索引就是段号,段号决定了在段表中的每一项的位置。有了这些信息,CPU就会通过段表找到对应的段在物理内存中的起始地址。然后CPU会去做一个比对,大小是否满足限制,满足则合法,否则将因非法访问异常,OS将处理。
寻址之前,段表就由OS建立了。
分页机制
分页和分段类似,也有页号,页内偏移;区别在于,段的尺寸是可变的,而页的大小是固定不变的。
划分物理内存至固定大小的帧,大小是2的幂。逻辑的页和物理的页都是一样的,物理的页帧是8K那么逻辑的页帧也是8K。Frame(帧)代表的是物理页,Page(页)代表的是逻辑页。OS需要建立的是逻辑页地址和物理页地址的映射关系。其中用到的有快表(TLB)和内存管理单元(MMU)。
页帧Frame
例题:
页Page
一个程序的逻辑空间被划分为大小相等的页。区别于页帧Frame,页号和帧号可能不同,但是页内偏移和帧内偏移是相等的。
程序运行,CPU(因执行指令或者访问数据)寻址,地址是一个逻辑地址,这个地址分为了p和o,然后将页号p作为索引index去查页表,页表存的是以页号为索引的对应项的帧号(frame number)。这个过程还需要页表基址(逻辑地址从哪开始)。有了这两个信息,就可以查到对应的帧号。我们可以通过页号查到帧号,帧号再加上偏移量,就是物理地址。
页表也是操作系统在操作系统初始化,在使能enable阶段建立好的。