文章目录
1、操作系统的内存管理主要是做什么
操作系统中内存管理的作用:
- 负责内存的分配与回收(malloc 函数:申请内存,free 函数:释放内存)
- 地址转换也就是将逻辑地址转换成相应的物理地址
逻辑(虚拟)地址
:我们编程一般只有可能和逻辑地址打交道,比如在 C 语言中,指针里面存储的数值就可以理解成为内存里的一个地址,这个地址也就是我们说的逻辑地址。逻辑地址由操作系统决定。物理地址
:物理地址指的是真实物理内存中地址,更具体一点来说就是内存地址寄存器中的地址。物理地址是内存单元真正的地址。
2、内存管理方式
分为连续分配管理方式和非连续分配管理方式
- 连续分配管理方式是指为一个用户程序分配一个连续的内存空间,常见的如 块式管理
- 非连续分配管理方式允许一个程序使用的内存分布在离散或者说不相邻的内存中,常见的如页式管理 和 段式管理
2.1 连续分配管理方式
- 块式管理 : 远古时代的计算机操系统的内存管理方式。将内存分为几个固定大小的块,每个块中只包含一个进程。如果程序运行需要内存的话,操作系统就分配给它一块,如果程序运行只需要很小的空间的话,分配的这块内存很大一部分几乎被浪费了。这些在每个块中未被利用的空间,我们称之为碎片。
内部碎片
:分出去内存空间的没用完,剩余的内存空间又不够请求所需的内存空间外部碎片
:还没有分配出去的内存空间,由于太小而无法分配给请求所需的内存空间
2.2 非连续分配管理方式
连续分配方式会形成许多内存碎片,虽可通过“紧凑”功能将碎片合并,但会付出很大开销。于是出现离散分配方式:将一个进程直接分散地装入到许多不相邻的内存分区中。
2.2.1 页式管理
2.2.1.1 步骤
- 逻辑空间等分为页,并从0开始编号
- 内存空间等分为块,与页面大小相同,从0开始编号
- 分配内存时,以块为单位将进程中的若干个页分别装入到多个可以不相邻接的物理块中。
用户程序的逻辑地址空间被划分成若干固定大小的区域,称为“页”或者“页面”,相应地,内存物理空间也分成相对应的若干个物理块,页和块的大小相等。可将用户程序的任一页放在内存的任一块中,实现了离散分配。
2.2.1.2 地址结构
分页地址中的地址结构如下:
- 12~31位为页号P,地址空间最多有1M页
- 0~11位为位移量W,即页内地址,每页大小为4KB;
- 逻辑地址 = 页号&位移量(&号是连接符号,是将页号作为逻辑地址的最高位)
2.2.1.3 地址映射(逻辑地址—>物理地址)
因为块的大小=页的大小,所以块内位移量=页内位移量,所以只需求出块号即可得出物理地址,因此,物理地址的计算方式为:物理地址=块号&块内地址
(&是连接符号)
2.2.1.4 页表
为了便于在内存中找到进程的每个页面所对应的物理块,系统为每个进程建立一张页表
,记录每页在内存中对应的物理块号,页表一般存放在内存中。
【例子】若页面大小为1K字节,页号2对应的物理块为b=8,计算逻辑地址A=2500的物理地址E。
- 逻辑地址:2500/1K=2 余数252,页号为2,页内地址=252
物理块号 8,块内地址252, 所以 物理地址=8*1K+252=8644
① 快表
为了解决虚拟地址到物理地址的转换速度,操作系统在 页表方案 基础之上引入了 快表 来加速虚拟地址到物理地址的转换,其中的内容是页表的一部分或者全部内容。
- 只有页表:CPU每次存取一个数据时需要访问2次内存,第一次访问页表,根据自己的页号找到相应的物理块号,第二次才是真正的访问那块内存,读写数据。
- 有了快表:有了快表,有时只要访问一次高速缓冲存储器,一次主存,这样可加速查找并提高指令执行速度。
使用快表之后的地址转换流程是这样的:
- 根据虚拟地址中的页号查快表;
- 如果该页在快表中,直接从快表中读取相应的物理地址;
- 如果该页不在快表中,就访问内存中的页表,再从页表中得到物理地址,同时将页表中的该映射表项添加到快表中;
- 当快表填满后,又要登记新页时,就按照一定的淘汰策略淘汰掉快表中的一个页。
② 多级页表
页表是一维的,只需要页号就能访问内存, 但是有可能表项庞大,一个页表就占了很大内存,这时提出了二级页表
,第一张页表的每一项存放一个页表的地址,所以第一张表是多张页表的索引
快表:加速虚拟地址到物理地址的转换
多级页表:解决虚拟地址空间大,页表也会很大的问题
2.2.1.5 地址变换原理及步骤
2.2.2 段式管理
2.2.2.1 步骤
- 逻辑空间分为若干大小不等的段,每段定义了一组有完整逻辑意义的信息
要注重理解完整的逻辑意义信息
- 对于页式管理,将程序分页时,页的大小是固定的,只根据页面大小大小死生生的将程序切割开
- 对于段式管理,分段时比较灵活,只有一段程序有了完整的意义才将这一段切割开。
- 内存空间为每个段分配一个连续的分区
- 分配内存时,以段为单位将进程中的若干个段分别装入到多个可以不相邻接的物理块中。
2.2.2.2 地址结构
分段地址中的地址具有如下结构:
-
16~31位为段号,地址空间最多有64K个段
-
0~15位为段内地址,每段大小为64KB;
段内地址的位数可以决定段的大小。 216=64
-
逻辑地址=段号&段内地址(&号是连接符号,是将段号作为逻辑地址的最高位)
2.2.2.3 地址映射(逻辑地址—>物理地址)
由逻辑地址得到段号、段内地址;再根据段号,由段表求出基址,再由基址+段内地址即可得到物理地址,计算公式为:物理地址=基址+段内地址(注意为+号,而不是&号)
2.2.2.4 段表
-
在分页管理中,每页的页长是固定的(块大小=页大小),找一个页只需要块号即可, 所以页表是一维的
-
在分段管理中,分段的大小是不固定的,找一个段需要两个信息(基址,段长),所以,段表是二维的
-
段表放在内存中,读写内存中的数据时,需要访问两次内存,同样的可以用快表的思想来解决(参考2.2.1.4)
2.2.2.5 地址变换原理及步骤
2.2.3 段页式管理
2.2.3.1 步骤
用户程序先分段,每个段内部再分页,并为每一个段赋予一个段名
上图是一个作业地址空间的结构:
- 该作业有三个段:主程序段、子程序段和数据段
- 页面大小为4KB
2.2.3.2 地址结构
在段页式系统中,其地址结构由段号、段内页号、页内地址三部分组成
2.2.3.3 地址映射(逻辑地址—>物理地址)
- 逻辑地址—>段号、段内页号、页内地址
- 段表寄存器—>段表始址
- 段号+段表始址—>页表始址
- 页表始址+段内页号—>存储块号
- 存储块号+页内地址—>物理地址
- 段表内容与分段系统略有不同,它不再是内存始址和段长,而是页表始址和页表长度
2.2.3.4 略
2.2.3.5 地址变换原理及步骤
2.2.4 页式管理和段式管理的共同点和区别
① 共同点
- 分页机制和分段机制都是为了提高内存利用率,较少内存碎片。
- 页和段都是离散存储的,所以两者都是离散分配内存的方式。但是,每个页和段中的内存是连续的。
② 区别
- 页的大小是固定的,由操作系统决定;而段的大小不固定,取决于我们当前运行的程序
- 分页仅仅是为了满足操作系统内存管理的需求,而段是逻辑信息的单位,在程序中可以体现为代码段,数据段,能够更好满足用户的需要
⑤ 总结
- 把主存分为大小相等且固定的一页一页的形式,相对于块式管理的划分力度更大,页较小,提高了内存利用率,减少了碎片。页式管理通过页表对应逻辑地址和物理地址。
- 页式管理虽然提高了内存利用率,但是页式管理中的页,实际并无任何实际意义。 段式管理把主存分为一段一段的,每一段的空间又要比一页的空间小很多 。但是,最重要的是段是有实际意义的,每个段定义了一组逻辑信息,例如,有主程序段 MAIN、子程序段 X、数据段 D 及栈段 S 等。 段式管理通过段表对应逻辑地址和物理地址。