内存的用户空间和内核空间:
Linux虚拟内存的大小为2^32(在32位的x86机器上),内核将这4G字节的空间分为两部分。最高的1G字节(从虚地址0xC0000000到0xFFFFFFFF)供内核使用,称为“内核空间”。而较低的3G字节(从虚地址0x00000000到0xBFFFFFFF),供各个进程使用,称为“用户空间”。因为每个进程可以通过系统调用进入内核,因此,Linux内核空间由系统内的所有进程共享。于是,从具体进程的角度来看,每个进程可以拥有4G字节的虚拟地址空间(也叫虚拟内存).每个进程有各自的私有用户空间(0~3G),这个空间对系统中的其他进程是不可见的。最高的1GB内核空间则为所有进程以及内核所共享。另外,进程的“用户空间”也叫“地址空间”,在后面的叙述中,我们对这两个术语不再区分。用户空间不是进程共享的,而是进程隔离的。每个进程最大都可以有3GB的用户空间。一个进程对其中一个地址的访问,与其它进程对于同一地址的访问绝不冲突。什么是内存?有何作用? 内存可存放数据。程序执行前需要先放到内存中才能被CPU处理——缓和CPU与硬盘之间的速度矛盾。
在多道程序环境下,系统中会有多个程序并发执行,也就 是说会有多个程序的数据需要同时放到内存中。那么会给内存的存储单元编地址。 内存地址从0 开始,每个 地址对应一 个存储单元。 如果计算机“按字节编址”, 则每个存储单元大小为 1字节,即 1B,即 8个二进制位。 如果字长为16位的计算机 “按字编址”,则每个存 储单元大小为 1个字;每个字的大小为 16 个二进制位。
指令的工作原理: 指令的工作基于“地址”。 每个地址对应一个数据的存储单元。
程序经过编译、链接 后生成的指令中指明 的是逻辑地址(相对地址),即:相对于进程的起始地址而言。 在逻辑空间中每条指令的地址和指令中要访问的操作数地址统称为逻辑地址 。很简单,逻辑地址就是你源程序里使用的地址,或者源代码经过编译以后编译器将一些标号,变量转换成的地址。
物理地址 :内存是由若干个存储单元组成的,每个存储单元有一个编号,这种编号可唯一标识一个存储单元(绝对地址)
虚拟地址 (virtual address): CPU启动保护模式后,程序运行在虚拟地址空间中。虚拟地址是Windows程序时运行在386保护模式下,这样程序访问存储器所使用的逻辑地址称为虚拟地注意,并不是所有的“程序”都是运行在虚拟地址中。CPU在启动的时候是运行在实模式的,Bootloader以及内核在初始化页表之前并不使用虚拟地址,而是直接使用物理地址的。
线性地址(Linear Address): 是逻辑地址到物理地址变换之间的中间层。在分段部件中逻辑地址是段中的偏移地址,然后加上基地址就是线性地址。
目标程序与可执行程序: 目标程序:又称为“目的程序”,为源程序经编译可直接被计算机运行的机器码集合,在计算机文件上以.obj作扩展名,由语言处理程序(汇编程序,编译程序,解释程序)将源程序处理(汇编,编译,解释)成与之等价的由机器码构成的。
可执行程序:目标代码尽管已经是机器指令,但是还不能运行,因为目标程序还没有解决函数调用问题,需要将各个目标程序与库函数连接(链接),才能形成完整的可执行程序。
程序如何运行: 编译:由编译程序(Compiler)将用户源代码编译成cpu可执行的目标代码,产生了若干个目标模块(Object Module)(即若干程序段)。形成的目标代码,每个目标代码都是以0为基址顺序进行编址,原来用符号名访问的单元用具体的数据——单元号取代。这样生成的目标程序占据一定的地址空间,称为作业的逻辑地址空间,简称逻辑空间。
链接: 由链接程序(Linker)将编译后形成的一组目标模块(程序段),以及它们所需要的库函数链接在一起,形成一个完整的装入模块(Load Module)。
装入:由装入程序(Loader)将装入模块装入物理内存。物理内存是真实存在的插在主板内存槽上的内存条的容量的大小。
装入的三种方式:
概述: 操作系统负责内存空间的分配与回收 内存空间的扩展:操作系统需要提供某种技术从逻辑上对内存空间进行扩充 操作系统需要提供地址转换功能,负责程序的逻辑地址与物理地 址的转换 操作系统需要提供内存保护功能。保证各进程在各自存储空间内 运行,互不干扰
内存空间的扩展: 覆盖技术:将程序分为多个段(多个模块)。 常用的段常驻内存,不常用的段在需要时调入内存。内存中分为一个“固定区”和若干个“覆盖区”。 需要常驻内存的段放在“固定区”中,调入后就不再 调出(除非运行结束) 不常用的段放在“覆盖区”,需要用到时调入内存, 用不到时调出内存。 交换技术:交换(对换)技术的设计思想:内存空间紧张时,系统将内存中某些进程暂时换出外存,把外存中 某些已具备运行条件的进程换入内存(进程在内存与磁盘间动态调度)
内存空间的分配与回收: 连续分配管理方式: 动态分区分配算法:
连续分配:为用户进程分配的必须是一个连续的内存空间。 非连续分配:为用户进程分配的可以是一些分散的内存空间。 什么是分页存储: 将内存空间分为一个个大小相等的分区(比如:每个分区4KB),每个分区就是一个“页框”(页框=页帧=内存块=物理 块=物理页面)。每个页框有一个编号,即“页框号”(页框 号=页帧号=内存块号=物理块号=物理页号),页框号从0开始。
将进程的逻辑地址空间也分为与页框大小相等的一个个部分, 每个部分称为一个“页”或“页面” 。每个页面也有一个编号, 即“页号”,页号也是从0开始。
操作系统以页框为单位为各个进程分配内存空间。进程的每个页面分别放入一个页框中。也就是说,进程的页面与内存的页 框有一一对应的关系。 各个页面不必连续存放,可以放到不相邻的各个页框中。
(注:进程的最后一个页面可能没有一个页框那么大。也就是 说,分页存储有可能产生内部碎片,因此页框不能太大,否则 可能产生过大的内部碎片造成浪费)
基本地址变换机构: 具有快表的地址变换机 构: 快表,又称联想寄存器(TLB, translation lookaside buffer ),是一种访问速度比内存快很多的高速缓存(TLB不是内存!),用来存放最近访问的页表项的副本,可以加速地址变换的速度。 与此对应,内存中的页表常称为慢表。
引入快表后,地址的变换过程: ① CPU给出逻辑地址,由某个硬件算得页号、页内偏移量,将页号与快表中的所有页号进行比较。 ② 如果找到匹配的页号,说明要访问的页表项在快表中有副本,则直接从中取出该页对应的内存块 号,再将内存块号与页内偏移量拼接形成物理地址,最后,访问该物理地址对应的内存单元。因此, 若快表命中,则访问某个逻辑地址仅需一次访存即可。 ③ 如果没有找到匹配的页号,则需要访问内存中的页表,找到对应页表项,得到页面存放的内存块 号,再将内存块号与页内偏移量拼接形成物理地址,最后,访问该物理地址对应的内存单元。因此, 若快表未命中,则访问某个逻辑地址需要两次访存(注意:在找到页表项后,应同时将其存入快表, 以便后面可能的再次访问。但若快表已满,则必须按照一定的算法对旧的页表项进行替换)
局部性原理: 时间局部性:如果执行了程序中的某条指令,那么不久后这条指令很 有可能再次执行;如果某个数据被访问过,不久之后该数据很可能再 次被访问。(因为程序中存在大量的循环) 空间局部性:一旦程序访问了某个存储单元,在不久之后,其附近的 存储单元也很有可能被访问。(因为很多数据在内存中都是连续存放 的)
两级页表:
分段存储管理方式: 进程的地址空间:按照程序自身的逻辑关系划分为若干个段,每个段都有一个段名(在低级语言 中,程序员使用段名来编程),每段从0开始编址 内存分配规则:以段为单位进行分配,每个段在内存中占据连续空间,但各段之间可以不相邻。
分段、分页管理的对比:
页是信息的物理单位。分页的主要目的是为了实现离散分配,提高内存利用率。分页仅仅是系统管 理上的需要,完全是系统行为,对用户是不可见的。段是信息的逻辑单位。分段的主要目的是更好地满足用户需求。一个段通常包含着一组属于一个逻辑模块的信息。分段对用户是可见的,用户编程时需要显式地给出段名。页的大小固定且由系统决定。段的长度却不固定,决定于用户编写的程序。分页的用户进程地址空间是一维的,程序员只需给出一个记忆符即可表示一个地址。分段的用户进程地址空间是二维的,程序员在标识一个地址时,既要给出段名,也要给出段内地址。分段比分页更容易实现信息的共享和保护。不能被修改的代码称为纯代码或可重入代码(不属于临 界资源),这样的代码是可以共享的。可修改的代码是不能共享的。段页式管理方式:
-优点缺点分页管理内存空间利用率高,不会产生外部 碎片,只会有少量的页内碎片不方便按照逻辑模块实现信息的共享和保护分段管理很方便按照逻辑模块实现信息的共 享和保护如果段长过大,为其分配很大的连续空间会很不方 便。另外,段式管理会产生外部碎片将进程按逻辑模块分段,再将各段分页(如每个页面4KB) 再将内存空间分为大小相同的内存块/页框/页帧/物理块 进程前将各页面分别装入各内存块中
传统存储管理方式的特征、缺点: 一次性:作业必须一次性全部装入内存后才能开始运行。这会造成两个问题: ①作业很大时,不能全 部装入内存,导致大作业无法运行; ②当大量作业要求运行时,由于内存无法容纳所有作业,因此只 有少量作业能运行,导致多道程序并发度下降。 驻留性:一旦作业被装入内存,就会一直驻留在内存中,直至作业运行结束。事实上,在一个时间段 内,只需要访问作业的一小部分数据即可正常运行,这就导致了内存中会驻留大量的、暂时用不到的 数据,浪费了宝贵的内存资源。
虚拟内存的定义和特征: 基于局部性原理,在程序装入时,可以将程序中很快 会用到的部分装入内存,暂时用不到的部分留在外存, 就可以让程序开始执行。 在程序执行过程中,当所访问的信息不在内存时,由 操作系统负责将所需信息从外存调入内存,然后继续 执行程序。 若内存空间不够,由操作系统负责将内存中暂时用不 到的信息换出到外存。 在操作系统的管理下,在用户看来似乎有一个比实际 内存大得多的内存,这就是虚拟内存
虚拟内存有三个主要特征: 多次性:无需在作业运行时一次性全部装入内存,而是允许被分成多次调入内存。 对换性:在作业运行时无需一直常驻内存,而是允许在作业运行过程中,将作业换 入、换出。 虚拟性:从逻辑上扩充了内存的容量,使用户看到的内存容量,远大于实际的容量。
请求分页存储管理与基本分页存储管理的主要区别: 在程序执行过程中,当所访问的信息不在内存时,由操作系统负责将所需信息从外存调入内存,然 后继续执行程序。 若内存空间不够,由操作系统负责将内存中暂时用不到的信息换出到外存。