内存
内存使用:
将程序放到内存中,PC指向开始地址,然后取指执行。
物理内存:
实际内存。
虚拟内存:
1. 每一个运行的进程,都会获得一个内存地址空间,这就是所谓的虚拟内存。
2. 这里面的所有地址都是虚拟的,和物理内存并不直接挂钩。
3. 这些虚拟地址所映射到的实际地址,可以是物理内存地址,也可以是页面文件的地址。
4. 如果物理内存小于这个虚拟地址的范围,
使用的时候可以将内存数据写入页面文件,通过清空内存数据,以提高物理内存的利用效率。
页面文件:
硬盘上的一块空间,在Windows下表现为一个文件。
这个页面文件存在的意义就是在物理内存被占用满以后,
将物理内存中的东西移动到硬盘上,腾出物理内存给需要的应用程序来使用。
内存管理
内存管理和虚拟内存管理:
内存管理包括:
程序装入等概念、
交换技术、
连续分配管理方式、
非连续分配管理方式(分页、分段、段页式)。
虚拟内存管理包括:
虚拟内存概念、
请求分页管理方式、
页面置换算法、页
面分配策略、
工作集、
抖动。
程序装入和链接
编译:
由编译程序将用户源代码编译成若干个目标模块。
链接:
由链接程序将编译后形成的一组目标模块,以及所需库函数链接在一起,形成一个完整的装入模块。
装入:
由装入程序将装入模块装入内存运行。
重定向(修改程序中的相对地址):
1. 编译时重定位的程序只能放在内存固定位置
2. 载入时重定位(静态重定位装入)的程序一旦载入内存就不能动了
3. 重定位最合适的时机:运行时重定位(动态重定位装入)
动态重定位的特点:
1. 可以将程序分配到不连续的存储区中。
2. 在程序运行之前可以只装入它的部分代码即可投入运行,然后在程序运行期间,根据需要动态申请分配内存。
3. 便于程序段的共享,可以向用户提供一个比存储空间大得多的地址空间。
内存保护
没有内存抽象的弊端:
1. 程序直接访问和操作的都是物理内存。
2. 用户程序可以访问任意内存,容易破坏操作系统,造成崩溃
3. 同时运行多个程序,可以相互访问内存,造成程序崩溃。
内存分配前,需要保护操作系统不受用户进程的影响,同时保护用户进程不受其他用户进程的影响。
通过 界地址寄存器 和 重定位寄存器 来实现这种保护:
界地址寄存器含逻辑地址值。
重定位寄存器含最小的物理地址值。
当CPU调度程序选择进程执行时,派遣程序会初始化 界地址寄存器 和 重定位寄存器。
每一个 逻辑地址 都需要与这两个寄存器进行核对,
如果未发生地址越界,则加上 重定位寄存器 的值后映射成物理地址,再送交内存单元。
以保证操作系统和其他用户程序及数据不被该进程的运行所影响。
内存连续分配管理方式
连续分配方式,是指为一个用户程序分配一个连续的内存空间。它主要包括:
1. 单一连续分配(分为系统区和用户区,无需内存保护,进程之间可见)
2. 固定分区分配(将用户内存空间划分为若干个固定大小的区域,每个分区只装入一道作业,容易产生浪费和不足)
3. 动态分区分配(不预先将内存划分,而是在进程装入内存时,
根据进程的大小动态地建立分区,并使分区的大小正好适合进程的需要)
内存非连续分配管理方式
允许一个程序分散地装入到不相邻的内存分区中。根据分区的大小是否固定分为:
1. 分页存储管理方式
2. 分段存储管理方式
内存分页
分区:
分为固定分区与可变分区,分配内存会产生效率问题(内存碎片)。
引入分页的目的:
解决内存分区导致的内存效率问题
分页存储管理方式根据运行作业时是否要把作业的所有页面都装入内存才能运行分为:
1. 基本分页存储管理方式
2. 请求分页存储管理方式
基本分页存储管理方式:
连续分区会产生外部碎片,对内存的利用率都比较低。
为了尽量避免碎片的产生,引入了分页的思想:
把主存空间划分为大小相等且固定的块,块相对较小,作为主存的基本单位。
每个进程也以块为单位进行划分,进程在执行时,以块为单位逐个申请主存中的块空间。
分页存储的几个概念:
a. 页面和页面大小。
进程(虚拟内存)中的块称为页(Page),
内存(物理内存)中的块称为页框(Page Frame,或页帧),
外存也以同样的单位进行划分,直接称为块(Block)。
进程在执行时需要申请主存空间,就是要为每个页面分配主存中的可用页框,这就产生了页和页框的一一对应。
b. 地址结构。
地址结构包含两部分:前一部分为页号 P,后一部分为页内偏移量 W。
地址长度为 32 位,其中 0~11 位为页内地址,即每页大小为 4KB ;12~31 位为页号,地址空间最多允许有 2^20 页。
c. 页表。
为了便于在内存中找到进程的每个页面所对应的物理块,
系统为每个进程建立一张页表,记录页面在内存中对应的物理块号,页表一般存放在内存中。
页表的作用是实现从页号到物理块号的地址映射。
分页管理方式存在的两个主要问题:
1. 每次访存操作都需要进行逻辑地址到物理地址的转换,地址转换过程必须足够快,否则访存速度会降低;
2. 每个进程引入了页表,用于存储映射机制,页表不能太大,否则内存利用率会降低。
多级页表:
为了提高内存空间利用率,页应该小。但是页小了,页表就大。
第一种尝试,只存放用到的页:用到的逻辑页才有页表项
但页表中的页号不连续,就需要比较、查找,折半,降低cpu效率。
既要连续又要让页表占用内存少:多级页表
将页表的10页空间也进行地址映射,建立上一级页表,用于存储页表的映射关系。
快表:
若页表全部放在内存中,则存取一个数据或一条指令至少要访问两次内存:
1. 一次是访问页表,确定所存取的数据或指令的物理地址
2. 二次才根据该地址存取数据或指令。
显然,这种方法比通常执行指令的速度慢了一半。
为此,在地址变换中增设了一个具有并行查找能力的高速缓冲存储器——快表,又称联想寄存器(TLB):
用来存放当前访问的若干页表项,以加速地址变换的过程。
与此对应,主存中的页表——慢表。
分页思想
分页问题
多级分页
分段(段面向用户/页面向硬件)
基本分段存储管理方式:
分页管理方式是从计算机的角度考虑设计的,以提高内存的利用率,提升计算机的性能。
且分页通过硬件机制实现,对用户完全透明。
而分段管理方式的提出则是考虑了用户和程序员,以满足方便编程、信息保护和共享、动态增长及动态链接等多方面的需要。
分段:
段式管理方式按照用户进程中的自然段划分逻辑空间。
例如,用户进程由主程序、两个子程序、栈、一段数据组成,
于是可以把这个用户进程划分为5个段,每段从 0 开始编址,
并分配一段连续的地址空间(段内要求连续,段间不要求连续,因此整个作业的地址空间是二维的)。
其逻辑地址由段号 S 与段内偏移量 W 两部分组成。
段表:
每个进程都有一张逻辑空间与内存空间映射的段表,其中每一个段表项对应进程的一个段,
段表项记录该段在内存中的起始地址和段的长度。
段的共享与保护:
在分段系统中,段的共享是通过两个作业的段表中相应表项指向被共享的段的同一个物理副本来实现的。
当一个作业正从共享段中读取数据时,必须防止另一个作业修改此共享段中的数据。
不能修改的数据是可以共享的,而可修改的代码和数据则不能共享。
段页式管理方式:
1. 页式存储管理能有效地提高内存利用率
2. 分段存储管理能反映程序的逻辑结构并有利于段的共享。
在段页式系统中,作业的地址空间首先被分成若干个逻辑段,每段都有自己的段号,
然后再将每一段分成若干个大小固定的页。
在进行地址变换时,首先通过段表查到页表起始地址,然后通过页表找到页帧号,最后形成物理地址。
程序段与段表
虚拟内存(virtual memory)
将用户逻辑内存和物理内存分开。在物理内存有限的情况下,为程序员提供了巨大的虚拟内存。
当访问虚拟内存时,会通过 MMU(内存管理单元)去匹配对应的物理地址:
如果虚拟内存的页并不存在于物理内存中,会产生缺页中断,从磁盘中取得缺的页放入内存。
如果内存已满,还会根据某种算法将内存中的页换出。
页面置换算法:
在缓存系统中,缓存的大小有限,当有新的缓存到达时,需要淘汰一部分已经存在的缓存,这样才有空间存放新的缓存数据。
页面置换算法的主要目标是使页面置换频率最低(也可以说缺页率最低)。
1. 先进先出(FIFO, First In First Out)
2. 改进型FIFO(Second Chance Page Replacement Algorithm)
3. 时钟替换(Clock Page Replacement Algorithm)
内存换入