操作系统 存储器管理存储管理

&&/&&&&/&&&&/&&
连续分配方式,是指为一个用户程序分配一个连续的内存空间。它主要包括单一连续分配、固定分区分配和动态分区分配。
单一连续分配
内存在此方式下分为系统区和用户区,系统区仅提供给操作系统使用,通常在低地址部分;用户区是为用户提供的、除系统区之外的内存空间。这种方式无需进行内存保护。
这种方式的优点是简单、无外部碎片,可以用覆盖技术,不需要额外的技术支持。缺点是只能用于单用户、单任务的操作系统中,有内部碎片,存储器的利用率极低。
固定分区分配
固定分区分配是最简单的一种多道程序存储管理方式,它将用户内存空间划分为若干个固定大小的区域,每个分区只装入一道作业。当有空闲分区时,便可以再从外存的后备作业队列中,选择适当大小的作业装入该分区,如此循环。
图3-4 &固定分区分配的两种方法
固定分区分配在划分分区时,有两种不同的方法,如图3-4所示。
分区大小相等:用于利用一台计算机去控制多个相同对象的场合,缺乏灵活性。
分区大小不等:划分为含有多个较小的分区、适量的中等分区及少量的大分区。
为便于内存分配,通常将分区按大小排队,并为之建立一张分区说明表,其中各表项包括每个分区的起始地址、大小及状态(是否已分配),如图3-5(a)所示。当有用户程序要装入时,便检索该表,以找到合适的分区给予分配并将其状态置为&已分配&;未找到合适分区则拒绝为该用户程序分配内存。存储空间的分配情况如图3-5(b)所示。
这种分区方式存在两个问题:一是程序可能太大而放不进任何一个分区中,这时用户不得不使用覆盖技术来使用内存空间;二是主存利用率低,当程序小于固定分区大小时,也占用了一个完整的内存分区空间,这样分区内部有空间浪费,这种现象称为内部碎片。
固定分区是可用于多道程序设计最简单的存储分配,无外部碎片,但不能实现多进程共享一个主存区,所以存储空间利用率低。固定分区分配很少用于现在通用的操作系统中,但在某些用于控制多个相同对象的控制系统中仍发挥着一定的作用。
图3-5 &固定分区说明表和内存分配情况
动态分区分配
动态分区分配又称为可变分区分配,是一种动态划分内存的分区方法。这种分区方法不预先将内存划分,而是在进程装入内存时,根据进程的大小动态地建立分区,并使分区的大小正好适合进程的需要。因此系统中分区的大小和数目是可变的。
图3-6动态分区
如图3-6所示,系统有64MB内存空间,其中低8MB固定分配给操作系统,其余为用户可用内存。开始时装入前三个进程,在它们分别分配到所需空间后,内存只剩下4MB,进程4无法装入。在某个时刻,内存中没有一个就绪进程,CPU出现空闲,操作系统就换出进程2,换入进程4。由于进程4比进程2小,这样在主存中就产生了一个6MB的内存块。之后CPU又出现空闲,而主存无法容纳进程2,操作系统就换出进程1,换入进程2。
动态分区在开始分配时是很好的,但是之后会导致内存中出现许多小的内存块。随着时间的推移,内存中会产生越来越多的碎片(图3-6中最后的4MB和中间的6MB,且随着进程的换入/换出,很可能会出现更多更小的内存块),内存的利用率随之下降。这些小的内存块称为外部碎片,指在所有分区外的存储空间会变成越来越多的碎片,这与固定分区中的内部碎片正好相对。克服外部碎片可以通过紧凑(Compaction)技术来解决,就是操作系统不时地对进程进行移动和整理。但是这需要动态重定位寄存器的支持,且相对费时。紧凑的过程实际上类似于Windows系统中的磁盘整理程序,只不过后者是对外存空间的紧凑。
在进程装入或换入主存时,如果内存中有多个足够大的空闲块,操作系统必须确定分配哪个内存块给进程使用,这就是动态分区的分配策略,考虑以下几种算法:
首次适应(First &Fit)算法:空闲分区以地址递增的次序链接。分配内存时顺序查找,找到大小能满足要求的第一个空闲分区。
最佳适应(Best &Fit)算法:空闲分区按容量递增形成分区链,找到第一个能满足要求的空闲分区。
最坏适应(Worst &Fit)算法:又称最大适应(Largest Fit)算法,空闲分区以容量递减的次序链接。找到第一个能满足要求的空闲分区,也就是挑选出最大的分区。
邻近适应(Next &Fit)算法:又称循环首次适应算法,由首次适应算法演变而成。不同之处是分配内存时从上次查找结束的位置开始继续查找。
在这几种方法中,首次适应算法不仅是最简单的,而且通常也是最好和最快的。在UNIX 系统的最初版本中,就是使用首次适应算法为进程分配内存空间,其中使用数组的数据结构 (而非链表)来实现。不过,首次适应算法会使得内存的低地址部分出现很多小的空闲分区,而每次分配查找时,都要经过这些分区,因此也增加了查找的开销。
邻近适应算法试图解决这个问题,但实际上,它常常会导致在内存的末尾分配空间(因为在一遍扫描中,内存前面部分使用后再释放时,不会参与分配),分裂成小碎片。它通常比首次适应算法的结果要差。
最佳适应算法虽然称为&最佳&,但是性能通常很差,因为每次最佳的分配会留下很小的难以利用的内存块,它会产生最多的外部碎片。
最坏适应算法与最佳适应算法相反,选择最大的可用块,这看起来最不容易产生碎片,但是却把最大的连续内存划分开,会很快导致没有可用的大的内存块,因此性能也非常差。
Kunth和Shore分别就前三种方法对内存空间的利用情况做了模拟实验,结果表明:
首次适应算法可能比最佳适应法效果好,而它们两者一定比最大适应法效果好。另外注意,在算法实现时,分配操作中最佳适应法和最大适应法需要对可用块进行排序或遍历查找,而首次适应法和邻近适应法只需要简单查找;回收操作中,当回收的块与原来的空闲块相邻时(有三种相邻的情况,比较复杂),需要将这些块合并。在算法实现时,使用数组或链表进行管理。除了内存的利用率,这里的算法开销也是操作系统设计需要考虑的一个因素。
表3-1三种内存分区管理方式的比较
界地址寄存器、越界
(用户空间划
上下界寄存器、越界检查机构
基地址寄存器、长度寄存器、动态地址转换机构
多道可变连续分配
以上三种内存分区管理方法有一共同特点,即用户进程(或作业)在主存中都是连续存放的。这里对它们进行比较和总结,见表3-1。5280人阅读
操作系统(9)
Linux为了有效使用机器中的物理内存,在系统初始化阶段内存被划分成几个功能区域:
其中,Linux内核程序占据在物理内存的开始部分,接下来是供硬盘等块设备使用的高速缓冲区部分(其中要扣除显卡内存和ROM BIOS所占用的内存地址范围)
当一个进程需要读取块设备中的数据时,系统会首先把数据读到高速缓冲区中。当有数据需要写到块设备上去时,系统也是先将数据放到高速缓冲区中,然后由块设备驱动程序写到相应的设备上。
内存的最后部分是可供所有程序随时申请和使用的主内存区。内核在使用主内存区时,首先要向内核内存管理模块提出申请,并在申请成功后方能使用。
在Intel 80386及以后的CPU中提供了两种内存管理(地址变换)系统:内存分段系统和分页系统。其中分页管理系统是可选择的,由系统程序员通过编程来确定是否采用。Linux同时采用了分段和分页机制。
内存地址空间概念
在Linux内核中,在进行地址映射操作时,我们要分清3种地址的概念:进程的虚拟(逻辑)地址、CPU的线性地址、实际的物理地址。
虚拟地址是指由程序产生的由段选择子和段内偏移地址两部分组成的地址。
(因为这两部分组成的地址并没有直接用来访问物理内存,而是需要通过分段地址变换机制或映射后才对应到物理内存地址上,故被称为虚拟地址。)
虚拟地址空间由GDT映射的全局地址空间和由LDT映射的局部地址空间组成。
【关于GDT和LDT,请移步-&CPU的实模式与保护模式&】
Intel 80x86 CPU可以索引16384个选择符。若每个段的长度都取最大值4GB,则最大虚拟地址空间范围是16384*4GB=64TB
CPU的内存管理给程序员提供了这样一个抽象的内存模型:
即程序员(无论是汇编的还是高级语言的)可以把内存分布看做是如上图所示,可以认为内存中只有自己的程序,自己独占CPU。
这是硬件和操作系统一起提供给程序员的简单抽象。
(底层的实现:地址变换、任务切换等对程序员是透明的)
逻辑地址是指由程序产生的与段相关的偏移地址部分。在Intel保护模式下即是指程序执行代码段限长内的偏移地址。
应用程序员仅需与逻辑地址打交道,而分段和分页机制对他来说完全透明的。(由加载器来设置分段)
Linux 0.12给每个进程都划分了容量为64MB的虚拟内存空间。因此出现的逻辑地址范围是0xx4000000。(即设置一个LDT所管辖的范围为64MB)
(现在的操作系统给进程划定的虚拟内存是4GB,当然也可以更多。)
有些资料不区分逻辑地址和虚拟地址的概念,统称逻辑地址。
线性地址是虚拟地址到物理地址变换之间的中间层,是CPU可寻址的内存空间中的地址。
程序代码会产生逻辑地址(或者说是段中的偏移地址),加上相应段的基地址就生成了一个线性地址。(一个段最大有4G的虚拟地址空间,在加载器把程序加载时,很容易选择一个空闲的段,填好GDT和LDT)
如果启用了分页机制,那么线性地址可以再经变换产生一个物理地址。若没有启用分页机制,那么线性地址直接就是物理地址。
Intel 80386的线性地址空间容量为4GB。
物理地址是指出现在CPU外部地址总线上的寻址物理内存的地址信号,是地址变换的最终结果地址。
内存分段机制
在实模式下,寻址一个内存地址主要是使用段基址和偏移值,段基址被存放在段寄存器中(如ds),并且段的长度被固定为64KB。段内偏移地址存放在任意一个可用于寻址的寄存器中(如si)。
在保护模式下,段寄存器中存放的不再是被寻址段的基地址,而是一个段描述符表中某一描述符项在表中的索引值。索引值指定的段描述符项中含有需要寻址的内存段的基地址、段的长度值、段的访问特权级等信息。(这样通过段描述符访问段中的信息,可检查安全性,则就是所谓的保护模式)
这样,在保护模式下寻址一个内存地址就需要比实模式下多一个环节,即需要使用段描述符表。
注意,如果你不在一个段描述符中定义一个内存线性地址空间区域,那么该地址区域就完全不能被寻址,CPU将拒绝访问该地址区域。
保存描述符项的描述符表有3种类型,每种用于不同目的。
IDT中断描述符表(Interrupt Descriptor Table),该表保存了定义中断或异常处理过程的段描述符。IDT表直接替代了8086系统中的中断向量表。(使得在跳转到中断程序时也进行权限检查。)
GDT全局描述符表(Globle Descriptor Table),该表可被所有程序用于引用访问一个内存段。
LDT局部描述符表(Local Descriptor Table),通常每个任务使用一个LDT表。每个LDT表为对应任务提供了更多的可用描述符项,因为也为每个任务提供了可寻址内存空间的范围。
这些表可以保存在线性地址空间的任何地方。为了让CPU能定位GDT表、IDT表和当前的LDT表,需要为CPU分别设置GDTR、IDTR和LDTR三个特殊寄存器。
可以看出,每个任务的局部描述符表LDT本身也是由GDT中描述符定义的一个内存段,在该段中存放着对应任务的代码段和数据段描述符,因此LDT段很短。同样,每个任务的任务状态段TSS也是由GDT中描述符定义的一个内存段。(TSS用于在任务切换时CPU自动保存或恢复相关任务的当前执行上下文)
内存分页管理
内存分页管理机制的基本原理是将CPU整个线性地址内存区域划分成4KB为1页的内存页面。程序申请使用内存时,系统就以内存页为单位进行分配。
为了在80x86保护模式下使用分页机制,需要把控制寄存器CR0的最高位置位。
对于Intel 80386系统,其CPU可以提供多达4GB的线性地址空间。
操作系统的内存管理(以下为一家之言,仅供参考)
有两套对内存管理的方式:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:237152次
积分:2956
积分:2956
排名:第8014名
原创:68篇
评论:113条
阅读:27319
文章:13篇
阅读:24681
文章:15篇
阅读:84124操作系统的存储管理功能包括_百度知道
操作系统的存储管理功能包括
存储保护内存分配,设备管理,存储扩充,网络服务 选哪几个
提问者采纳
内存分配,存储保护,存储扩充,
提问者评价
其他类似问题
为您推荐:
您可能关注的推广
存储管理的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁2661人阅读
CPU直接访问的存储器只有内存和处理器内的寄存器。
1.基本硬件
&&&&& CPU可以在一个cpu时钟内执行一个或多个其内置寄存器的指令。而访问内存需多个cpu时钟。由于内存频繁访问,可以再cpu与内存之间增加高速缓存
&&&&& 为确保进程有独立的内存空间,可用基地址寄存器和界限地址寄存器来确立一个合法地址以供其他进程访问。基地址寄存器含有最小的合法物理内存地址,界限地址寄存器决定合法地址大小。如基地址和界限地址寄存器分别为3,那么合法地址为3
2.逻辑地址空间与物理地址空间
&&&&& 内存在字节的地址为物理地址,cpu生成的地址为逻辑地址。通常逻辑地址为虚拟地址,从虚拟地址到物理地址的映射是由称为内存管理设备单元MMU的硬件来完成的。
&&&&& 用户进程只生成逻辑地址,且认为其地址空间为0到max。逻辑地址使用前需映射到内存的物理地址。MMU动态的将逻辑地址加上重定位寄存器的值后映射成物理地址。映射后的物理地址再送交内存单元。
3.连续分配内存
&&&&&内存通常分为两个区域,分别驻留操作系统和用户进程。由于中断向量通常位于低内存,操作系统也放在低内存。
3.1内存映射与保护
&&&&& 通过重定位寄存器和界限地址寄存器可保护内存进程的独立空间。当cpu调度器选择一个进程执行时,作为上下文切换的一部分,调度程序会用正确的值初始化重定位寄存器和界限地址寄存器,保证其他进程不受该进程运行所影响。
3.2内存分配
&&&&& 最为简单的内存分配方法是MFT,即将内存分为多个固定大小的分区,一个分区容纳一个进程。MFT已不再使用,MVT是他的推广,主用用于批处理系统。
&&&&& 在可变分区方案里,系统中有一个表用来记录那些内存占用还是未占用。当有新进程需要内存时,为该内存寻找足够大的孔,从这个孔中为该进程分配所需的内存,孔内未分配的内存可为其他进程所用。从一组可用孔中选择一个空闲孔最常用的方法有:首次适应、最佳适应、最差适应。首次适应最快最好
&&&&& 首次适应和最佳适应都有外部碎片问题。并不连续的小内存称为碎片。 解决碎片问题方法之一是允许物理地址空间为非连续:分页与分段。
&&&&& 传统上,分页由硬件处理。最近的设计是通过将硬件和系统相配合来实现分页的。
&& && 进程需要在内存中以便运行,不过进程可以暂时从内存中交换到备份存储,当需要再次执行时再调回到内存中。如果进程地址绑定方式是在汇编时或加载时所定的,他只得移到原来内存空间。如果绑定是在运行时才确定,由于物理地址是在运行时才确定的,进程可移到不同地址空间。
4.1基本方法
&&&&& 基本方法涉及将物理内存分为固定大小的块,称为帧(frame),而将逻辑内存也分为同样大小的块,称为页。当执行进程时,其页从备份存储(他也分固定大小的块,大小与内存帧一样)中调入到可用的内存帧中。
&&&&& 由CPU生成的每个地址分为两个部分:页号P和页偏移d,页号作为页表的索引。页表包含每页所在物理内存的基地址,这些基地址与页偏移的组合就形成了物理地址,可送交给物理单元。
&&&&& 页与帧的大小一样,是由硬件决定的。页的大小通常为2的幂,方便将逻辑地址转为页号和页偏移,根据计算机结构的不同,从512B到16M不等。
&&&&& 当进程需要执行时,根据进程的大小计算页数n,从而内存中也应该至少有n个帧用来分配给新进程。进程的第一页装入一个分配的帧,帧号放入进程的页表中。
&&&&& 如下图所示
&&&&&&&&&&&&&&&&&&&& &&&&
&&&&& 页大小为4B,而逻辑内存为32B(8页),逻辑地址0的页号为0,页号0对应帧5,因此逻辑地址映射为物理地址5*4+0=20.逻辑地址3映射物理地址5*4+3=23.。逻辑地址13映射到物理地址9.
&&&&& 采用分页技术不会产生外部碎片,但可能产生内部碎片。内存的分配是以帧为单位进行的,每个进程平均可有半个帧大小的内部碎片。
&&&&& 分页使用户视角的内存与实际物理内存想分离。用户无法访问其他用户程序占用的内存。
4.2硬件支持
&&&&& 页表的硬件实现有多种方法。最简单的是将页表作为一组专用寄存器来实现
&&&&& 分页环境下,内存保护是通过与每个帧相关联的保护位来实现的。这新保护位通常位于页表中。可用一个位来定义一个页是可读写的还是只读的的,当对一个只读的页进行写操作会使系统产生硬件陷阱。
&&&&& 分页的一个优点是可以看、共享公共代码,这种考虑对分时环境很重要。
5.页表结构
5.1层次页表
&&&&& 大多数计算机系统支持大逻辑地址空间(2的32到64的幂)。这种情况下,页表本身非常大。我们并不可能在内存中连续的分配这个表。一个简单方法是将页表划分为更小部分。
&&&&& 一种方法是使用两级分页算法,将页表在分页。以一个4kb页大小的32位系统为例。一个逻辑地址被分为20位的页码和12位的页偏移。因为要对页表进行再000分页,所以该页号可分为10位的页码和10位 的页偏移。这样一个逻辑地址就表示如下形式:
&&&&&&&&&&&&
&&&&& p1是用来访问外部页表的索引,p2是外部页表的页偏移,采用这种结构地址转换方法如下图所示。由于地址转换由外向内,这种方案也称为向前映射页表。
&&&&&&&&&&&&
5.2哈希页表
&&&&& 处理超过32位地址空间的常用方法是使用哈希页表(hashed page& table),并以虚拟页码作为哈希值。哈希页表的每一条目都包括一个链表的元素,这些元素哈希成同一位置。每个元素有三个域:虚拟页码 所映射的帧号 指向链表中下一个元素的指针。
&&&&& 虚拟地址中的虚拟页号转换到哈希表中,用虚拟页号与链表中的每一个元素的第一个域相比较。如果匹配,那么相应的帧号就用来形成物理地址。如果不匹配,就对链表中的下一个节点进行比较,以寻找一个匹配的页号:
&&&&&&&&&&&&&&&
&&&&& 群集页表类似于哈希页表,对于稀疏地址空间很有用,稀疏地址空间的地址引用不连续,且分散在整个地址空间
5.3反向页表
&&&&& 通常每个进程都有一个相关页表。每个页表有很多项。这可能消耗大量物理内存。为解决这个问题,可以使用反向页表。
&&&&& 采用分页内存管理有一个不可避免的问题:用户视角的内存和实际内存的分离。分段支持这种用户视角:将内存看做一个线型数组,有的包含指令,有的包含数据。
&&&&& 逻辑地址空间是由一组段组成的。每个段都有名字和长度。地址指定了段名称和段内偏移。因此用户通过两个量来指定地址:段名称和偏移。段是编号的,通过段号而非段名称来引用。因此逻辑地址由有序对构成:
&&&&&&&&&& &segment-number,offset&
通常,编译程序时,编译器会自动根据输入程序来构造段。
&&&&& 一个C编译器可能创建如下段:代码、 全局变量、堆、线程栈、C库函数。
&&&&& 段表的每个条目都有段基地址和段界限。段基地址包括段在内存中的开始物理地址,段界限指定段长度&&
&&&&& 一个逻辑地址段号S和偏移d组成。段号用作段表的索引,逻辑地址的偏移d应位于0和段界限之间。段偏移一段基地址之和就是物理内存地址。因此段表是一组基地址和界限寄存器对。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&& 如图有5个段,编号0~4,例如段2为400B开始于位置4300.对段2第53字节的引用映射成位置=4353
&&&&&&&&&&&&&&&&&&&&&&&&&&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:18240次
排名:千里之外
原创:23篇

我要回帖

更多关于 操作系统 的文章

 

随机推荐