为了能将用户程序装入内存,必须为它分配一定大小的内存空间。在早期的操作系统中,特别是60-80年代出现了连续分配的方式,该分配方式为一个用户程序分配一个连续的内存空间,即程序中的代码或数据的逻辑地址相邻,体现在内存空间分配时物理地址相邻。 但连续分配的方式会产生很多的“碎片”,而为了解决这些碎片,产生了离散分配的思想,即允许将一个进程直接分散的装入到许多不相邻接的分区中,充分利用内存。于是产生了一下三种方式:
分页存储管理方式分段存储管理方式段页存储管理方式把用户程序的地址空间按系统规定的逻辑页划分为大小相等的部分。这个划分是由系统自动完成的并且对用户是透明的。 相应,也会把内存的物理地址空间分为若干个块,同样也给予不同的编号。在为进程分配内存的时候,以块为单位,将进程中的若干页分别装入到多个可以不相临接的物理块中。在这个过程中由于最后一页经常形成装不满的一块而形成了不可利用的碎片,称为“页内碎片”。
页面的大小一般是2的K次幂(K=9~16)。通常是1kB-8kB。
选择的页面太小:虽然一方面可以减小内存碎片,起到减少内存碎片空间的作用,有利于内存利用率的提高。但会导致每个进程占据较多的页面,使得进程的页表过长,占用大量的内存。选择的页面过大:虽然减少了页表的长度,提高了页面换进换出的效率,但是却导致碎片增大。它包含两部分内容:前一部分为页号P,后一部分为位(偏)移量W,即页内地址。对于特定的机器,其地址结构是一定的。若给定一个逻辑地址空间中的地址为A,页面的大小为L,则页号P和页内地址d,可以按以下公式求得:
P = INT[A/L] INT是求整函数 d = [A] MOD L MOD是取余函数。
例如其系统页面大小为1KB,设为A=2170B,由上式可得:P=2,d=122。
上图根据地址长度计算主存大小,页面大小? 有图可知,主存容量是由地址结构长度决定的。所以主存的大小为:2^32B = 4GB 0-11是页内地址,即每页的大小为:2^12 = 4096B = 4KB。在分页系统中,允许进程的页分散的存入内存中的任意一块物理块上,并且能够保证进程的运行,系统又为每一个进程建立了一张页面映像表,简称页表。
在进程地址空间的所有页(0-n),依次在页表中有一个页表项,其中记录了相应页在内存中对应的物理块号。同时在页表项中还设置了一存储控制字段。如果进程违规请求操作该块的时候就会引发一次中断。页表是大多是驻留在内存中的,在进程执行的时候,页表寄存于系统中的页表寄存器(PTR),在其中存放页表在内存的始址和页表长度。当进程没有执行的时候,页表的首地址和长度存于该进程的PCB中。而占用处理机的当前进程的页表首地址和长度需要放在地址映射机构的页表首地址寄存器和页表长度寄存器。按系统规定的逻辑页大小划分的大小相等的区域。从0开始编块号。进程的页就是放入其中的。
物理块表:整个系统有一个物理块表,描述物理内存空间的分配使用情况。用到的数据结构:位示图,空闲块链表。内存是按照块为单位进行分配的,并按应用程序的页数多少来分配。逻辑上相邻的页,物理上不一定相邻。页的大小=块的大小,因此上面的32位的系统,页的大小为4kb = 块的大小也为4kb。进程在运行的期间,需要对程序和数据的地址进行转换,即将用户地址空间中的逻辑地址变换为内存空间中的物理地址。
分页系统中的地址映射:通常和地址映射的概念一样。即把程序地址转换为内存地址。这个地址转换过程是在程序执行过程中完成的。是动态的地址映射。
计算程序在内存中的地址:
进程访问某个逻辑地址中的数据的步骤: (1) 分页地址变换机构自动将有效地址转换为页号和页内地址两个部分。 (2)再以页号为索引去检索页表。在这个过程中系统会自动进行信息保护: 如果页号位于该页表中,则将页表始址与页号和页表项长度相乘积。
某页表项在页表中的位置 = 页号 * 页表项长度 + 页表始址
(3)找到对应的页表项在内存中的地址后,可从中获得物理块号,将其装入物理地址寄存器中。 (4)同时将有效地址寄存器中的页内地址送入物理地址寄存器的块内地址字段中。这样便完成了从逻辑地址到物理地址的变换。
|外层页号|外层页内地址|页内地址|
3. 二级页表地址映射过程: 4. 三级页表的出现: 近两年推出的64位系统中,把直接寻址的存储器空间减少为45位长度(即245)左右,这样便能够使用三级页表进行管理了。 5. 三级页表结构及其地址映射过程
在系统中,类似于分页系统,需要为每个进程建立一张映射表,简称“段表”。每个段在段表中有一个表项,其中记录了该段在内存中的起始地址(又称基址)和段的长度。 进程通过查找段表,找到每个段所对应的内存区。可见,段表是用于实现从逻辑地址到物理内存区的映射。
段表结构:(1)在进行地址变换的时候,系统将逻辑地址中的段号S与段表长度进行比较TL,如果S>TL,表示段号太大,于是访问越界,于是产生越界信号中断。若未越界,则根据段表的始址和该段的段号,计算出该段对应的段表项的位置,从中读出改段在内存中的起始地址。 (2)然后检查段内地址d是否超过该段的段长SL,若超过,即d>SL,同样发生越界中断信号。若未发生越界,则将该段的基址d与段内地址相加,即可得到要访问的内存物理地址。
段页式系统的基本原理是:分段和分页原理的结合,即先将用户程序分为若干段,在把每个段分为若干个页,并为每一个段赋予一个段名。
(1)利用段号S,将它与段长TL进行比较。若S<TL,表示未越界,于是利用段表始址和段号来求出该段所对应的段表项在段表中的位置,从中得到该段的页表始址。 (2)并利用逻辑地址中的段内页号P来获得对应页的页表项位置,从中读出该页所在的物理块号b。 (3)再利用块号b和页内地址来构成物理地址。
这里可以对应了段页式三次访问内存的特点:
第一次:访问段表取得页表始址。第二次:访问内存页表,取出物理块号,并将物理块号与页内地址一起形成指令或数据物理地址。第三次:这次才是真正的从第二次访问所得的地址中取出指令。由于三次访问的原因,因此段页式也形成了快表的查询方式。增设一个高速缓冲寄存器,每次去访问它时,利用段号和页号去检索,找到匹配的就获得其物理块号。 如果没找到仍然需要第三次去访问内存。
内存管理博文链接