内存管理的主要功能有:
在进行具体的内存管理之前,需要了解进程运行的基本原理和要求。
内存管理就是就是围绕这五个方面展开的。
创建进程首先要将程序和数据装入内存。将用户源程序变为可在内存中执行的程序,通常需
要以下几个步骤:
●编译。由编译程序将用户源代码编译成若干目标模块。
●链接。由链接程序将编译后形成的- -组目标模块及它们所需的库函数链接在- -起,形成一个完整的装入模块。
●装入。由装入程序将装入模块装入内存运行。
程序的链接有三种方式:
内存的装入模块在装入内存时,同样有以下三种方式:
(1)绝对装入
绝对装入方式只适用于单道程序环境。在编译时,若知道程序将驻留在内存的某个位置,则编译程序将产生绝对地址的目标代码。绝对装入程序按照装入模块中的地址,将程序和数据装入内存。由于程序中的逻辑地址与实际内存地址完全相同,因此不需对程序和数据的地址进行修改。另外,程序中所用的绝对地址,可在编译或汇编时给出,也可由程序员直接赋予。而通常情况下在程序中采用的是符号地址,编译或汇编时再转换为绝对地址。
(2)可重定位装入
在多道程序环境下,多个目标模块的起始地址通常都从0开始,程序中的其他地址都是相对于起始地址的,此时应采用可重定位装入方式。根据内存的当前情况,将装入模块装入内存的适当位置。在装入时对目标程序中指令和数据地址的修改过程称为重定位,又因为地址变换通常是在进程装入时一次完成的,故称为静态重定位。
当一个作业装入内存时,必须给它分配要求的全部内存空间,若没有足够的内存,则无法装
入。此外,作业一旦进入内存,整个运行期间就不能在内存中移动,也不能再申请内存空间。
(3)动态运行时装入
也称动态重定位。程序在内存中若发生移动,则需要采用动态的装入方式。装入程序把装入模块装入内存后,并不立即把装入模块中的相对地址转换为绝对地址,而是把这种地址转换推迟到程序真正要执行时才进行。因此,装入内存后的所有地址均为相对地址。这种方式需要一个重定位寄存器的支持。
动态重定位的优点:可以将程序分配到不连续的存储区;在程序运行之前可以只装入部分代
码即可投入运行,然后在程序运行期间,根据需要动态申请分配内存;便于程序段的共享。
确保每个进程都有一个单独的内存空间。内存分配前,需要保护操作系统不受用户进程的影.响,同时保护用户进程不受其他用户进程的影响。内存保护可采取两种方法: .
并不是所有的进程内存空间都适合共享,只有那些只读的区域才可以共享。可重入代码又称纯代码,是一种允许多个进程同时访问但不允许被任何进程修改的代码。但在实际执行时,也可以为每个进程配以局部数据区,把在执行中可能改变的部分复制到该数据区,这样,程序在执行时只需对该私有数据区中的内存进行修改,并不去改变共享的代码。
交换技术主要在不同进程( 或作业)之间进行,而覆盖则用于同一个程序或进程中。对于主.存无法存放用户程序的矛盾,现代操作系统是通过虚拟内存技术来解决的,覆盖技术则已成为历史;而交换技术在现代操作系统中仍具有较强的生命力。
内存在此方式下分为系统区和用户区,系统区仅供操作系统使用,通常在低地址部分:在用户区内存中,仅有一道用户程序,即整个内存的用户空间由该程序独占。这种方式的优点是简单、无外部碎片,无须进行内存保护,因为内存中永远只有一道程序。缺点是只能用于单用户、单任务的操作系统中,有内部碎片,存储器的利用率极低。
固定分区分配是最简单的一种多道程序存储管理方式,它将用户内存空间划分为若干固定大
小的区域,每个分区只装入一道作业。当有空闲分区时,便可再从外存的后备作业队列中选择适
当大小的作业装入该分区,如此循环。在划分分区时有两种不同的方法。
又称可变分区分配,它是在进程装入内存时,根据进程的实际需要,动态地为之分配内存,并使分区的大小正好适合进程的需要。因此,系统中分区的大小和数目是可变的。
在进程装入或换入主存时,若内存中有多个足够大的空闲块,则操作系统必须确定分配哪个
内存块给进程使用,这就是动态分区的分配策略。考虑以下几种算法:
首次适应算法最简单,通常也是最好和最快的。不过,首次适应算法会使得内存的低地址部分出现很多小的空闲分区,而每次分配查找时都要经过这些分区,因此增加了开销。
邻近适应算法试图解决这个问题。但它常常导致在内存空间的尾部(因为在- -遍扫描中,内存前面部分使用后再释放时,不会参与分配)分裂成小碎片。通常比首次适应算法要差。
最佳适应算法虽然称为“最佳”,但是性能通常很差,因为每次最佳的分配会留下很小的难以利用的内存块,会产生最多的外部碎片。
最坏适应算法与最佳适应算法相反,它选择最大的可用块,这看起来最不容易产生碎片,但是却把最大的连续内存划分开,会很快导致没有可用的大内存块,因此性能也非常差。
非连续分配方式根据分区的大小是否固定,分为分页存储管理和分段存储管理。在分页存储管理中,又根据运行作业时是否要把作业的所有页面都装入内存才能运行,分为基本分页存储管理和请求分页存储管理。
基本分页存储管理是指将主存和辅存分成若干个大小相等的页,以页为单位进行数据的读写和存储。在基本分页存储管理中,每个进程都有自己的页表,用于记录该进程的逻辑地址与物理地址之间的映射关系。
当进程需要访问某个逻辑地址时,首先通过页表将逻辑地址转换成物理地址,并判断该物理地址是否已经在主存中。如果该物理地址所对应的页不在主存中,则发生缺页中断,操作系统负责将该页从辅存中调入主存,更新页表,并重新执行该指令。如果该物理地址所对应的页已经在主存中,则直接访问该页并执行相应的操作。
基本分页存储管理可以提高内存的利用率,使得多个进程可以同时共享主存。但是在实现过程中,需要考虑到页面置换算法、页表的管理以及缺页中断的处理等问题。
基本分段存储管理是指将主存和辅存分成若干个大小不等的段,以段为单位进行数据的读写和存储。在基本分段存储管理中,每个进程都有自己的段表,用于记录该进程的逻辑地址与物理地址之间的映射关系。
当进程需要访问某个逻辑地址时,首先根据该地址所属的段,在段表中查找该段的物理地址,并计算出物理地址偏移量。然后将物理地址偏移量加上段的物理地址,得到最终的物理地址,并执行相应的操作。
在基本分段存储管理中,不同的进程可以共享相同的段,从而减少了内存的浪费。但是在实现过程中,需要考虑到段的分配、段的保护、段表的管理以及地址转换等问题。同时,由于段的大小不同,因此还需要考虑段的碎片化问题。
基本段页式存储管理是指将主存和辅存分成若干个大小不等的段和页,以段和页为单位进行数据的读写和存储。在基本段页式存储管理中,每个进程都有自己的段表和页表,用于记录该进程的逻辑地址与物理地址之间的映射关系。
当进程需要访问某个逻辑地址时,首先根据该地址所属的段,在段表中查找该段所对应的页表的物理地址,并计算出该地址所对应的页的物理地址。然后在页表中查找该页的物理地址,并计算出物理地址偏移量。最后将物理地址偏移量加上页的物理地址,得到最终的物理地址,并执行相应的操作。
在基本段页式存储管理中,可以实现不同进程之间的空间隔离和内存共享,从而提高了内存的利用率。但是在实现过程中,需要考虑到段的分配、段的保护、页表的管理、页面置换算法以及缺页中断的处理等问题。同时,由于段的大小不同,也会带来段的碎片化问题。
请求分页式存储管理是基于基本分页存储管理的一种改进,它可以提高页面置换算法的效率,并减少缺页中断的次数。在请求分页式存储管理中,每个进程所占用的物理页面数量并不是固定的,而是根据进程的实际需要来动态地进行分配。
具体来说,当一个进程需要申请一页新的物理页面时,操作系统会进行以下步骤:
通过动态地分配物理页面,请求分页式存储管理可以避免浪费物理内存的情况发生,并且可以根据进程的实际需要来动态地分配物理内存,从而提高了内存的利用率。同时,请求分页式存储管理还可以根据不同的页面置换算法,如FIFO和LRU等,来选择最优的页面置换策略,从而减少缺页中断的次数,提高系统的性能。
在计算机组成原理中,也涉及到虚拟内存这一知识点,在那里我有详细解释,这里就不赘述了。
点我了解虚拟存储技术
本文是从操作系统角度了解的内存管理,可以结合从计算机组成原理一起观看效果更佳。