连续分配方式程序员
连续分配方式指的是为一个用户程序划分为连续的内存空间。能够把连续分配方式进一步分为单一连续分配、固定分区分配、动态分区分配和可重定位分区分配四种方式。算法
1.单一连续分配数据结构
在单道程序系统中,任什么时候刻只有一个用户程序驻留在内存。内存被划分两部分:系统区(供操做系统使用)和用户区(用来存储用户程序和数据)。编码
2.固定分区分配 spa
单一连续分配只能存一个程序,为了能同时存储多个用户程序,将内存分为多个分区,每一个分区的大小固定,这就是所谓的固定分区分配。这些分区大小在操做系统初始化的时候就肯定了,每一个分区只能存放一个用户程序。固定式分区能够两种方式:各分区大小相同和分区大小不一样。为了对分区进行分配和管理,一般按照分区大小的排队,并为之创建一张分区使用表。当用户程序须要分配内存空间的时候,系统检索该表,从表中找到一个大小知足要求且没有被分配出去的分区,分配给用户程序。这个分配方式的缺点是会产生内碎片,由于分区固定,分配给用户的内存空间不是刚好匹配,这样就产生内碎片。
操作系统
3.动态分区分配指针
为了减小内碎片,同时提升系统的利用率,人们提出了动态分区的概念。所谓动态分区是指事先先划定分区的大小,根据进程的大小动态的为之分配内存。为了实现动态分配,系统中必须配置相应的数据结构,用来描述空闲分区和已分配分区,为分配提供依据。经常使用的数据结构:空闲分区表和空闲分区链(双向链表,每一个分区的起始部分设置一些分区信息和前向指针,每一个分区的尾部设有后向指针)。进程
某个进程须要内存时,系统必需要找到可以知足需求的一个分区,一般知足需求的可能不止一个,具体分配哪个由不一样的分配策略来决定:内存
(1)首次适应算法(first-fit):从链表头开始查找,分配找到的第一个知足要求的分区。缺点是低地址充分利用,高地址很空。随着做业的增多,地址留下不少碎片。it
(2)下次适应算法(next-fit):不是从头查找,而是从上次查找的地方继续往下查找。
(3)最佳适应算法(best-fit):老是给内存请求者分配最适合它大小的空闲分区,提升内存利用率。实验代表,这种方法最差,由于会致使不少的内碎片。
(4)最坏适应算法(worst-fit):对任何给定的请求都使用当前可用的最大分区。
4.可重定位分区分配
这种分配方式在动态分区分配的基础上加上了内存紧凑技术。
连续分配方式中要求做业存放在一个连续的内存空间中。当内存中没有足够大的空间知足用户的请求时,这时可内存中一些小的内存空间合并成一个大的空间,这种技术叫做内存紧凑技术。实现这种技术把已占有空间挪到一块儿,没被占有的碎片空间挪到一块儿组成一个大的空间,这样就能知足用户的请求。
这种技术须要动态重定位技术配合,即一个做业装入内存后全部的地址仍然是相对地址,在执行时转换为绝对地址,即做业的地址能够在内存中随时移动。这样在内存的紧凑的时候只须要改变重定位寄存器能将做业的起始地址改变。
基本分页分配方式
分页存储管理将做业的逻辑地址划分一系列同等大小的页,将各个页从0开始编码。同时将内存也划分一样大小的连续空间,称之为块或页框。只有内存中有足够多的页框就可以存下用户做业,各页框能够不相邻。页框的大小应该始终(512B-8KB)。
分页系统中的地址结构由两部分组成:页号和页偏移量。
在分页系统中,页的存放能够是连续的也能够是不连续的,这就增长了逻辑地址到物理地址的难度(由于不连续)。为此,系统为每一个进程建立了一个页表,在逻辑空间中的每一页,依次在页表中有一个表项,记录了对应的物理块号。看下图:
注:上面的转换是由硬件完成的,由专用的寄存器 (页表寄存器),而加法只是一个拼接,高20位物理页号与低12位偏移量拼接成最后的物理地址。
从上面的分析能够发现地址变换的第一步就是检索页表。为了实现快速检索页表,最好把页表放在寄存器中,每一个表项用一个寄存器实现。若是每页的大小为4KB,则32位地址将有1M个页面,即有一个1M个页表项,每一个页表项若是占1B,则页表将占用1MB。系统中设有一个页表寄存器,存储了页表的开始地址和页表长度。平时进程未执行的时候,页表的开始地址和页表的长度存放在PCB中,当进程运行时,将这两个数据导入到页表寄存器。
因为页表时放在内存中的,那么访问一次数据须要两次访问内存,第一次访问页表,第二次找到对应的物理块号与偏移量拼接造成物理地址。 为了提升速率,在地址变化机构中增长一个TLB(所谓的快表),用来存放当前访问过页表项。给定一个地址首先在快表中查找,找不到才转向页表查找。
因为页表占有1MB,且页表的空间是连续存储的,这显然是不对的。解决的办法是对把页表看出普通的文件,对页表再分页存储就造成了所谓的多级页表。可是随着页表的分页级数增长,访问内存的次数也就要增长,这样会增长系统的开销,因此慎重。下面是一个二级页表的图:
另外,页面选择不易过大(内碎片严重),不易太小(访问内存的次数就增长了)。
基本分段分配方式
分页存储管理能够实现内存利用率的提升,可是一个独立的逻辑段被离散的放在不少物理块中,不少时候程序员但愿把一个程序按照它的逻辑结构存放。
一个程序的逻辑段在程序运行过程当中有的大小会发生变化,例如数据段和堆段。而有的逻辑段的大小运行过程当中不发生变化,如代码段。在分页存储管理方式中,对于随时动态增大的段的存储管理是很是困难的,一旦涉及到段的增大涉及到从新分配物理块,那么就涉及增长页表的修改过程。(说简单点,分别创建来了数据段,代码段,堆栈段)
分页系统中,过程被一个一个牢牢的存放在一块儿,中间没有空隙。这就致使修改一个过程的大小会影响到其余地的起始地址,进而须要修改全部调用被移动的进程,以使它们访问指向这些过程的新地址。一样,在分页系统中,一个逻辑段可能存放n个物理块中,若是几个程序共享这段代码,须要在每一个程序填加相应的表项,增长开销。
分段存储系统中,逻辑地址包括段号和段偏移量。
分段系统中,系统为每一个分段分配一个连续的分区,进程的各个段能够离散地装入内存中的不一样的分区中。为了实现逻辑地址到物理地址的转换,在系统中为每一个进程创建一个段表。(逻辑地址到物理地址转换跟分页系统同样,只不过查找的是段表)
分段系统经过不一样进程段表中的行指向同一段地址来实现代码的共享。(段的大小是不固定的)。
注:倘若共享一个160K代码,若是有10个用户程序须要共享这段代码。在分页系统中,这个共享代码有40个页表项(假设每页大小4K),则每一个用户程序须要添加40个页表项,则总共要添加40*10 = 400个表项。而若是是分段系统的话,只须要额外的添加10个段表项就好了。是否是节省了空间。
段页式分配方式
在段页式存储管理中,用户地址空间被划分为多个段并每一个段予一个段名,对每一个段在划分为多个固定大小的页,页大小就是主存中物理块的大小。
在段页式系统中,地址由段号、段内页号和页内地址。
在段页系统中,为了将逻辑地址转换为物理地址,须要查找段表和段内页表。段表中存放的页表的起始地址和页表长度。在段内系统中为了得到一条指令或者数据,须要三次访问内存。为了提升执行速度,在地址变化机构中增长一个高速缓冲寄存器,每次访问它时,都续同时利用段号和页号去检索高速缓冲。找不到匹配项时,按照正常的段表-》页表顺序去查找。