【操作系统】第四章非连续内存分配

简介: 【操作系统】第四章非连续内存分配

为什么需要非连续内存分配来管理物理内存?

现有的管理方法:

1、分段 2、分页(其中最重要的是页表的设计与组成)


连续内存分配的缺点:

  • 分配个一个程序的物理内存是连续的
  • 内存利用率较低
  • 有外碎片,内碎片的问题


非连续分配的优点:

  • 一个程序的物理地址空间是非连续的
  • 更好的内存利用和管理
  • 允许共享代码与数据(共享库等…)
  • 支持动态加载和动态链接


非连续分配的缺点:

  • 如何建立虚拟地址和物理地址之间的转换
  • 软件方案:开销较大
  • 硬件方案:分段和分页


4.1非连续内存分配:分段


分段的管理机制分为两点:

1)在分段情况下,内存地址空间如何寻址的问题

2)如何去实现分段的寻址方案


一、分段

计算机程序是由各种各样的段来存储的

image.png

分段:更好的分离和共享

image.png

通过分段,可以有效的隔离开来,相应的分离出来,更加有效进行管理,分配和保护。这中间需要一种映射机制来实现相关联。

image.png

映射之后:位置不一样,大小也不一样


二、段的访问机制

将一个一维的地址分成两块:

一个是段号的寻址,另一个是偏移的寻址

image.png

段号+段内偏移何合在一起就形成了一段机制来寻址的方式。


分两种情况:

1)段寄存器+地址寄存器实现方案(x86)

2)将段和段内偏移合在一起,单地址实现方案


三、将段的映射机制映射起来

image.png

过程:

1、通过段号找到段所在物理内存的起始地址

2、但是这个映射关系需要存储–段表,段表中存储中逻辑地址的段号和物理地址的段号的映射关系。

3、段表中存储着两个重要的信息:一个是段表的起始地址,另外一个是段长度的限制,两者合在一起就形成了一个物理地址。

4、 这样形成了物理地址之后,根据这个地址来查找在物理内存的位置,然后把相应的数据取出来,交给cpu做进一步的处理

段表有操作系统来建立,此时段机制就可以正常的工作了。

而且段机制用得比较少,现在大多数的cpu用的是分页机制。


4.2非连续内存分配:分页


两个内容:

1)分页地址空间

2)页寻址方案

段需要一个段号和段内的偏移,而页也一样,需要页号和页内的偏移。

主要区别在于在段的机制里面,段的尺寸是可变的,而分页机制中页的大小是固定的,这个是最大的区别。


一、页的分类

划分物理内存至固定大小的帧

大小是2的幂,eg:512,4096(4k),8192

划分逻辑地址空间至相同大小的页

大小是2的幂,eg:512,4096,8192

ps:页的大小是不变的,这样便于硬件对其实现

页帧(frame)是物理页

页(page)逻辑页

我们需要建立一个逻辑页地址和物理页地址的一个映射关系。

建立方案:转换逻辑地址为物理地址(page to frame)

1)页表

2)MMU(内存管理单元)/TLB(块表)


二、页帧(frame)—物理地址

定义:物理内存的组织和布局方式

页帧也有两部分组成:

1)页帧号(frame number)

2)页帧偏移(frame offset)

image.png

页帧号占 F 位,页帧本身的大小占 S 位

在整个的寻址空间中有 2^F 这么多个页帧的个数

页帧而每一页的总大小是 2^S

image.png

解析:

一帧包含了9位,所以没一页帧的大小都是2 ^9 这么大小,而页帧号是3,所以代表了有3个这么大的一个页,所以也就是2^9 * 3,最后,再加上偏移量o,为6,所以最后的结果是 2^9 * 3 + 6 = 1542.

所以地址就是0x1542


三、页(page)—逻辑地址

和页帧的区别是其页号和页帧号的szie大小可能不一样。但是每一个页的大小和每一个页帧的大小都是一样的。

image.png

其逻辑地址的计算方法与页帧的计算方法是一样的。


四、地址的转换

image.png

过程如下:

1、首先cpu会去寻址(逻辑地址或者是物理地址),这个地址会分为另两个内容,一个是offect偏移量,一个是页号。

2、将也号作为一个索引,查一个页表(Page table),其实以页号为索引的一向内容,可以根据其查找出页帧号。而且还有知道其基地址,就形成了页帧号和页帧偏移量大小的物理地址。(所以页的偏移大小和页帧的偏移大小是一样的)

3、这样就知道了对应的物理地址的所在位置。这个整个的大致过程。

ps:其中page table是操作系统在内存初始化的时候建立起来的。

image.png


4.3非连续内存分配:页表-概述、TLB


一、页表的结构

在页表中,有一系列的属性,eg:可读可写,是否存在等等…

image.png


二、页表的地址转换的例子

image.png

逻辑地址空间和物理地址空间大小是不对等的,但是每一个页内的偏移都是相等的。

其中,resident 位为0 代表 内存不存在,为1表示存在。如果cpu访问了为0的地址,这是会产生一个异常,就是内存访问异常。

如图所示:

页为(4,0)的逻辑地址,由于resident = 0,所以真是的物理内存不存在

页为(3,1024)的逻辑地址,由于resident = 1,地址存在,查表可知,frame物理地址的页帧号是4,偏移量与页的偏移量相同,一样为1023,所以结果地址便为(4,1023)

(页表的建立过程是有操作系统完成的)


三、分页机制的性能问题

1、空间的代价问题

2、时间的开销问题

(希望时间越短越好,效率越大越好)


问题一:页表可能非常大

64位机器如果每页是1k,那么一个页表的大小会是多少呢?

问题二:页表可能开销大

每一个应用程序都要生成一个自己的页表,开销比较大


如何处理?

1)缓存(Caching)

将一些常用的数据缓存到黎cpu非常近的地方,提高访问的速度

2)间接(Indirection)访问

通过间接的方法,将一个很大的空间,拆分为一个很小的空间。通过多级的页表机制,可以缓解页表占用空间过大的问题。


时间问题 —TLB

缓存近期访问的页帧转换表项

image.png

TLB是一个特殊的区域,位于CPU的内部。

Key和Value两个形成了TLB的表相,而这个表相是由相关存储器来实现的,这个是一种快速查询的存储器,速度很快,可以并发的查找,但是容量是有限的。所以可以将一些经常使用的页表项放在TLB中。可以通过查询TLB,避免了一次页表的访问。

当出现TLB访问不到的情况,这个情况叫做TLB miss,这是cpu就不得不查页表。

而对于TLB miss这个情况,将新的页帧加载到TLB中,部分是有cpu硬件来完成的,而部分是有操作系统完成的,也就是两种情况都存在。


4.4非连续内存分配:页表-二级、多级页表


一、空间问题 — 二级页表解决

image.png

一级页表里面存储的是二级页表的地址,二级页表知道之后就会知道frame number页帧号。

通过这种方式可以极大的减少空间的消耗,因为如果一级页表中的resident = 0的话。就没有必要再二级页表中添加其索引的,比单级页表大大的减小了空间的开销。


二、多级页表

多级页表可以表示一个更大的地址空间,形成一个树状的结构。这个是以时间换取空间,但是时间问题也可以通过TLB方法来解决。

image.png


4.5非连续内存分配:页表-反向页表


一、反向页表:

以物理地址的页帧号(frame number)方向查找逻辑页的页号(page number)

image.png

这样使得寄存器的容量,只与物理地址空间的大小相关,与逻辑地址空间大小无关。

但是有一个主要的问题:如何将页号和页帧号建立起一个映射关系。


页存储器方案的权衡:

优点:

1)转换表的大小相对于物理内存来说很小

2)转换表的大小跟逻辑地址空间的大小无关


缺点:

1)需要的信息对调了,既根据帧号可找到页号

2)如何转换回来?既根据页号找到帧号

3)在需要在反向表中搜索想要的页号


二、关联存储器方案

可以并行的查找页号所对应的帧号,其key是他的页号,value是页帧号

image.png

存在的问题:

1)设计成本太大,硬件处理很复杂

2)内存访问的开销问题

3)大量的关联内存非常昂贵,难以在单个时钟周期内完成且耗电


三、基于哈希(hash)计算的反向页表

只需要建立好一个哈希的函数,输入一个值,就会得到一个输出。而输入的值是page number,输出的值是frame number。

为了能提高加速,需要硬件的加速。

为了提高效率,加一个PID的标识

image.png

可以有效的缓解完成映射的开销。

在反向页表中通过哈希算法来搜索一个页对应的帧号

1)对页号做哈希计算,为了在“帧表”(每一帧用于一个表项)中获取对应的帧号

2)页i被放置在表中f(i)位置,其中f是设定的哈希函数

3)为了查找页i,执行下列操作:

计算哈希函数f(i)并且使用它作为页寄存器表的索引,获取对应的页寄存器,检查寄存器标签是否包含i,如果包含,则代表成功,否则失败。


参考链接:https://www.bilibili.com/video/av6538245?p=19

目录
相关文章
|
2月前
|
存储 Linux 调度
深入理解操作系统:从进程管理到内存分配
【8月更文挑战第44天】本文将带你深入操作系统的核心,探索其背后的原理和机制。我们将从进程管理开始,理解如何创建、调度和管理进程。然后,我们将探讨内存分配,了解操作系统如何管理计算机的内存资源。最后,我们将通过一些代码示例,展示这些概念是如何在实际操作系统中实现的。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和深入的理解。
|
3月前
|
安全 索引
操作系统中的内存管理策略
【8月更文挑战第23天】
80 1
|
23天前
|
分布式计算 算法 大数据
探索操作系统的核心:调度与内存管理机制
【10月更文挑战第11天】 本文深入探讨了操作系统中两大核心功能——调度与内存管理机制。通过分析调度算法、进程状态转换及内存分配策略等关键方面,揭示了它们如何共同维护系统性能和稳定性。旨在为读者提供对操作系统内部运作的深刻理解,同时引起对优化策略的思考。
50 5
|
1月前
|
算法
深入理解操作系统:内存管理机制的探索之旅
【10月更文挑战第2天】在数字世界的浩瀚海洋中,操作系统犹如一艘精密的航船,承载着软件与硬件的和谐共舞。本文将揭开内存管理的神秘面纱,从基础概念到高级策略,引领读者领略操作系统内存分配的智慧。通过深入浅出的解释和生动的比喻,我们一同遨游在内存的江河之中,感受操作系统如何巧妙地协调资源,确保数据的有序流动。让我们跟随内存的脚步,探索那些隐藏在每次点击、每次命令背后的奥秘。
|
1月前
|
监控 开发者
深入理解操作系统:内存管理的艺术
【10月更文挑战第2天】在数字世界的幕后,操作系统扮演着至关重要的角色。本文将深入探索操作系统的心脏——内存管理,揭示它是如何协调和管理计算机的宝贵资源。通过浅显易懂的语言和生活化的比喻,我们将一起走进内存管理的奥秘世界,了解它的原理、机制以及为何对整个系统的性能和稳定性有着不可替代的影响。无论你是技术新手还是资深开发者,这篇文章都将为你打开新的视角,让你对日常使用的设备有更深层次的认识和尊重。
|
1月前
|
缓存 算法 调度
深入浅出操作系统:从进程管理到内存优化
本文旨在为读者提供一次深入浅出的操作系统之旅。我们将从进程管理的基本概念出发,逐步深入到内存管理的复杂世界,最终探索如何通过实践技巧来优化系统性能。文章将结合理论与实践,通过代码示例,帮助读者更好地理解操作系统的核心机制及其在日常技术工作中的重要性。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往操作系统深层次理解的大门。
|
1月前
|
存储 算法 C语言
MacOS环境-手写操作系统-17-内存管理算法实现
MacOS环境-手写操作系统-17-内存管理算法实现
31 0
|
1月前
|
Java C语言 iOS开发
MacOS环境-手写操作系统-16-内存管理 解析内存状态
MacOS环境-手写操作系统-16-内存管理 解析内存状态
31 0
|
1月前
|
存储 算法 C语言
MacOS环境-手写操作系统-15-内核管理 检测可用内存
MacOS环境-手写操作系统-15-内核管理 检测可用内存
33 0
|
2月前
|
Python
python对电脑的操作,获取几核,获取操作系统,获取内存
python对电脑的操作,获取几核,获取操作系统,获取内存