分段与分页内存管理

一、背景   

采用固定分区的方式,会产生页内碎片等缺点,因此引入了动态分区方式。但动态分区又产生了外部碎片,导致内存的利用率也不理想。所以不管是固定分区还是动态分区,都存在三个问题:

  • 进程地址空间保护问题。 所有的用户进程都可以访问全部的物理内存, 所以恶意程序可以修改其他程序的内存数据, 这使得进程一直处于危险的状态下。
  • 内存使用效率低。如果即将运行的进程所需要的内存空间不足,就需要选择一个进程进行整体换出,这种机制导致大量的数据需要换出和换入,效率非常低下。
  • 程序运行地址重定位问题。进程在每次换出换入时使用的地址都是不固定的,这给程序的编写带来了麻烦,因为访问数据和指令跳转时的目标地址通常是固定的,所以就需要使用重定位技术了。

二、虚拟内存

站在内存使用的角度看,进程大概在 3 个地方需要用到内存。

  • 进程本身。比如,代码段以及数据段用来存储程序本身需要的数据。
  • 栈空间。程序运行时需要分配内存空间来保存函数调用关系、局部变量、函数参数以及函数返回值等内容,这些也是需要消耗内存空间的。
  • 堆空间。程序运行时需要动态分配程序需要使用的内存,比如,存储程序需要使用的数据等。

不管是的固定分区还是动态分区, 进程需要包含上述 3 种内存, 如图 所示。

但是,如果我们直接使用物理内存,在编写这样一个程序时,就需要时刻关心分配的物理内存地址是多少、内存空间够不够等问题。

后来,设计人员对内存进行了抽象,把上述用到的内存抽象成虚拟内存。进程不用关心分配的内存在哪个地址,它只管使用。最终由处理器来处理进程对内存的请求,经过转换之后把进程请求的虚拟地址转换成物理地址。这个转换过程称为地址转换(address translation), 而进程请求的地址可以理解为虚拟地址(virtual address)。


我们在处理器里对进程地址空间做了抽象,让进程感觉到自己可以拥有全部的物理内存。进程
可以发出地址访问请求,至于这些请求能不能完全满足, 那就是处理器的事情了。总之,进程
地址空间是对内存的重要抽象, 让内存虚拟化得到了实现。 进程地址空间、 进程的 CPU 虚拟化
以及文件对存储地址空间的抽象,共同组成了操作系统的 3 个元素。

三、分段机制

基于进程地址空间这个概念, 人们最早想到的一种机制叫作分段(segmentation) 机制, 其
基本思想是把程序所需的内存空间的虚拟地址映射到某个物理地址空间。
分段机制可以解决地址空间保护问题,进程 A 和进程 B 会被映射到不同的物理地址空间,
它们在物理地址空间中是不会有重叠的。因为进程看的是虚拟地址空间,不关心实际映射到哪
个物理地址。

如果一个进程访问了没有映射的虚拟地址空间,或者访问了不属于该进程的虚拟地址空间,那么 CPU 会捕捉到这次越界访问,并且拒绝此次访问。同时 CPU 会发送异常错误给操作系统,由操作系统去处理这些异常情况,这就是我们常说的缺页异常。

另外,对于进程来说,它不再需要关心物理地址的布局,它访问的地址位于虚拟地址空间,只需要按照原来的地址编写程序并访问地址,程序就可以无缝地迁移到不同的系统上。

在分段式存储管理系统中,进程按照逻辑关系划分为若干个段,每个段都是从0开始编址,并有自己的名字和长度。所以要访问的逻辑地址是由段名(段号)和段内偏移量(段内地址)决定。

为每个分段分配一个连续的分区,而进程中的各个段可以离散地装入内存中不同的分区中。
为使程序能正常运行,即能从物理内存中找出每个逻辑段所对应的位置,在系统中为每个进程建立一张段映射表,简称“段表”
每个段在表中占有一个表项,其中记录了该段在内存中的起始地址(“基址”)和段长(字节)。段表一般放在内存中。在配置了段表后,执行中的进程可通过查找段表找到每个段所对应的内存区。

虽然分段机制有了比较明显的改进,但是内存使用效率依然比较低。分段机制对虚拟内存到物理内存的映射依然以进程为单位。当物理内存不足时,换出到磁盘的依然是整个进程,因此会有大量的磁盘访问,进而影响系统性能。

站在进程的角度看,对整个进程进行换出和换入的方法还不太合理。在运行进程时,根据局部性原理,只有一部分数据一直在使用。若把那些不常用的数据交换出磁盘,就可以节省很多系统带宽,而把那些常用的数据驻留在物理内存中也可以得到比较好的性能。因此,人们在分段机制之后又发明了一种新的机制,这就是分页
(paging)机制。

四、分页存储管理

程序运行所需要的内存往往大于实际物理内存, 采用传统的动态分区方法会把整个程序交换
到交换磁盘, 这不仅费时费力, 而且效率很低。 后来出现了分页机制, 分页机制引入了虚拟存储
器的概念。

分页机制的核心思想是让程序中一部分不使用的内存可以存放到交换磁盘中, 而程序正在使用的内存继续保留在物理内存中。 因此, 当一个程序运行在虚拟存储器空间中时, 它的寻址范围由处理器的位宽决定,

比如 32 位处理器的, 位宽是 32 位, 地址范围是 0~4 GB。 64 位处理器的虚拟地址位宽是 48 位,程序员可以访问 0x0000000000000000~0x0000FFFFFFFFFFFF 以
及 0xFFFF000000000000~0xFFFFFFFFFFFFFFFF 这两段空间。

在使能了分页机制的处理器中,我们通常把处理器能寻址的地址空间称为虚拟地址(virtual address)空间。和虚拟存储器对应的是物理存储器(physical memory),它对应着系统中使用的物理存储设备的地址空间,比如DDR 内存颗粒等。在没有使能分页机制的系统中,处理器直接寻址物理地址,把物理地址发送到内存控制器;而在使能了分页机制的系统中,处理器直接寻址虚拟地址,这个地址不会直接发给内存控制器, 而是先发送给内存管理单元(Memory Management Unit, MMU)。

MMU负责虚拟地址到物理地址的转换和翻译工作。在虚拟地址空间里可按照固定大小分成若干个大小相等的片,称为页面或页,典型的页面粒度为 4 KB,现代处理器都支持大粒度的页面,比如 16 KB、 64 KB 甚至 2 MB 的巨页,并为各页加以编号,从0开始,如第0页、第1页等。 而在物理内存中, 空间也分成和虚拟地址空间大小相同的块, 称为页帧(page frame)。

程序可以在虚拟地址空间里任意分配虚拟内存,但只有当程序需要访问或修改虚拟内存时,操作系统才会为其分配物理页面, 这个过程叫作请求调页(demand page)或者缺页异常(pagefault)

五、页表

在分页系统中,允许将进程的各个页离散地存储在内存不同的物理块中,但系统应能保证进程的正确运行,即能在内存中找到每个页面所对应的物理块,为了描述进程的内存分布情况,引入一个单独的数据结构页表)。系统为每个进程都建立了一张页面映像表,简称页表。(页号到块号的地址映射)。

若将整张页表存放在寄存器中,则会占
用很多硬件资源,因此通常的做法是把页表放在主内存里,通过页表基地址寄存器来指向这种
页表的起始地址。 如图 14.3 所示, 处理器发出的地址是虚拟地址, 通过 MMU 查询页表, 处理
器便得到了物理地址,最后把物理地址发送给内存控制器
 

在一个32位机中,当页面大小为4kB时,它的页内偏移量(也称为页内地址)所占的位数最大为2的12次方,即需要12位,所以0~11位是页内偏移量,其余的12~31位存放页号。如下图

看这里

地址转换是分页系统必须实现的功能。可以设置 一个缓冲器来进行地址转换,即快表。由于快表成本的原因,快表不能很大,通常在16~512个页表之间。快表中只存放当前使用频繁的页表

在操作系统中引入快表是为了加快地址映射速度。在虚拟页式存储管理中设置了快表,作为当前进程页表的Cache。通常快表处于MMU中。
 

六.   段页式存储管理

为了解决分段的外部碎片问题,再次将“页”引入,即把一个段划分为许多页,形成两者的集合体,称为段页式存储管理。这是现代操作系统采用的最多的方式,而单纯的分页存储,分段存储从来就没被采用过(哈哈)。同理,将页划分为段,就称为页段式存储。不过一般段比页要大得多,所以都用段页式。

现在逻辑地址就是如下状态:

现在逻辑地址

由于进程的段不多,所以段的位数比较少。32位机上通常是8位,即256个段。如果页面大小为4KB,那么页内地址12位,段地址8位,段内页号32-8-12=12位,即一个段有4K大小的页。

一个段内的每个页都可以装入内存的页框(块)中去。所以与分页系统一样,这里也有一个页表,来记录段的页的内存驻留情况。进程的段也需要一个段表来记录,以实现分段保护和共享等功能。

地址转换这里也是用快表,利用硬件也完成地址转换。这里复杂一些,需要分别获取段表,页表。所以产生了额外的内存开销

七、总结

在页式、段式存储管理中,为获得一条指令或数据须两次访问内存(一次访问页表/段表,一次访问内存取真正的内存单元);

而段页式则须三次访问内存(第一次是由段表地址寄存器得段表始址后访问段表,由此取出对应段的页表在内存中的地址。  第二次则是访问页表得到所要访问的物理地址。  第三次才能访问真正需要访问的物理单元

参考:

分段机制:从历史到现代的演变与应用-优快云博客

https://zhuanlan.zhihu.com/p/578529437

linux-----页、页表、页框(块)_一个页框有多少字节-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值