大家好,欢迎来到IT知识分享网。
什么是虚拟内存?
虚拟内存(Virtual Memory)是一种计算机内存管理技术,它使得应用程序认为它们拥有连续的可用内存(一个大的地址空间),即使实际上可能被分散在物理内存和磁盘存储中。虚拟内存通过地址映射机制将程序使用的虚拟地址转换为物理地址,从而使得计算机系统可以更高效地利用内存资源。
为什么要有虚拟内存?
在单片机时代,我们如果想要运行程序,需要手动将代码烧录进去,同时单片机的 CPU 是直接操作内存的物理地址的,这也就意味着:两个任务试图访问或修改同一个内存地址时,可能会互相覆盖写入的数据,导致程序崩溃或行为异常。
为了解决这个问题,我们可以把进程所使用的地址隔离开来,让操作系统为每个进程分配独立的虚拟地址,同时每个进程都不能访问物理地址,由操作系统提供一种机制,将不同进程的虚拟地址和不同内存的物理地址做映射,这一步对进程来说是透明的。
操作系统引入了虚拟内存,进程持有的虚拟地址会通过 CPU 中的内存管理单元 MMU 的映射关系转换成物理地址,然后再通过物理地址去访问内存。
这样每个进程都有自己的虚拟地址空间,进程之间互不干扰。这增加了系统的安全性和稳定性,因为一个进程无法直接访问或修改另一个进程的内存。
通过虚拟内存,操作系统可以保护各个进程的内存空间,防止非法访问。这有助于防止程序错误和恶意行为导致系统崩溃或数据损坏。
内存分段
分段是一种内存管理技术,它将内存分成大小不等的段。每个段代表一个逻辑单元,如代码段、数据段、堆栈段等。虚拟地址由段号和段内偏移组成,段表(Segment Table)用于将段号映射到物理地址。
简单来说就是:段表中的段基地址 + 虚拟地址中的段内偏移量 = 物理地址。
内存分段存在的问题
- 内存碎片
内存碎片可分为内部内存碎片和外部内存碎片。
内存分段技术可以做到段根据实际需求来分配内存,即有多少需求就分配多大的量,所以不会出现内部内存碎片。
但由于每个段的长度并不固定,所以多个段不一定能恰到好处地利用完所有的内存空间,这会产生若干个不连续的小的物理内存,致使新的程序无法被装载,所以存在外部内存碎片。
- 内存交换的效率低
解决外部内存碎片的方法就是通过内存交换,将内存中的数据写入到磁盘,再从磁盘写回内存中紧密排列,这样就能重新整理出空闲的物理内存空间。
在 Linux 系统中,这个内存交换空间也就是常见的 Swap 空间,它是从磁盘中划分出来用于内存与磁盘做空间交换的。
但是显而易见,对于多进程系统而言,采用分段的方式,产生外部内存碎片的概率是很高的,这就会导致频繁地 Swap 内存区域,同时磁盘的 I/O 是很慢的,所以每一次内存交换都会造成一定的性能瓶颈。
内存分页
分页是将虚拟内存和物理内存分成固定大小的块,称为页(Page)和页框(Frame)。虚拟地址由页号和页内偏移组成,页表负责将页号映射到物理内存中的页框。
简单来说就是:页表中的基地址 + 虚拟地址中的页内偏移量 = 物理地址。
页表是存储在内存里的,内存管理单元 MMU 负责将虚拟内存地址转换成物理地址。
由于内存分页的内存空间都是预先划分好的,所以不会出现内存分段中段与段之间会产生碎片的问题,但由于分配内存的最小单位是一页,即使程序不足一页大小也会至少分配一个页,所以会存在页内内存浪费,产生内部内存碎片的问题。
如果内存空间不足,操作系统会把其他正在运行的进程中最近没被使用的内存页给释放掉,即换出 Swap Out 到磁盘,当需要访问该页数据时,再 Swap In 加载进内存。所以一般来说只需要操作极少数的页,内存交换的效率就相对较高。
综上,分页机制允许我们在加载程序时,不需要一次性将所有程序都加载进内存,而是可以选择性地在建立虚拟地址和物理地址的映射关系后,等到需要时再加载。
内存分页的缺点?
每个页表项(PTE)需要额外的内存来存储地址映射信息。如果进程的地址空间很大,则需要更大的页表,从而增加内存开销。
为了解决简单分页造成的额外内存开销,就引申出了多级页表,这里可以简单地类比成数据库索引结构中的多叉树。基于计组原理中的局部性原理,我们可以这样实现:如果某个一级页表的页表项没有被用到,那么就不需要创建它对应的二级页表,等到需要使用的时候再创建…以此类推多级页表,就能极大地减少内存的占用。
但是页表的多级结构(如二级或三级页表)虽然减少了单级页表的大小,但也会增加额外的查找开销。
TLB 是什么?
TLB(Translation Lookaside Buffer,翻译后备缓冲)是一种用于提高虚拟内存系统性能的高速缓存。TLB存储虚拟地址到物理地址的映射,从而减少访问页表的次数,加快地址转换的速度。
简单来说,就是针对多级页表增加了查询开销的问题,同样是基于局部性原理,把最常访问的几个页缓存起来,即 CPU 中的 TLB,也称为页表缓存、转址旁路缓存、快表。
- 查找顺序
- 当 CPU 生成一个虚拟地址并需要转换为物理地址时,会首先查找 TLB
- 如果 TLB 命中(找到对应的映射),则直接使用该映射进行内存访问
- 如果 TLB 未命中,则需要访问页表来获取映射,并将该映射加载到 TLB 中
- TLB 更新
- 当 TLB 未命中并从页表中获取新的映射后,需要将新的映射加载到 TLB 中
- 如果 TLB 已满,需要使用某种替换策略(如 LRU,Least Recently Used,最近最少使用)来选择一个旧的映射进行替换
- TLB 刷新
当发生上下文切换(context switch)时,不同进程的页表不同,需要刷新 TLB,以防止进程 A 的地址映射被进程 B 错误使用。某些系统使用地址空间标识符(ASID,Address Space Identifier)来避免在上下文切换时完全刷新 TLB。
- 多级 TLB
为了进一步提高性能,某些高性能处理器使用多级 TLB(如一级 TLB 和二级 TLB),一级 TLB 速度更快但容量较小,二级 TLB 容量更大但速度稍慢。这种结构可以在保持高命中率的同时,提供更大的缓存空间。
段页式内存管理
段页式内存管理(Segmented Paging Memory Management)是一种结合了分段(segmentation)和分页(paging)两种内存管理技术的混合机制。它利用分段的灵活性和分页的高效性,以便更好地管理内存,提高内存利用率,并提供更强的保护和隔离。
在段页式内存管理中,内存地址转换包括两个步骤:首先通过分段机制找到段,然后通过分页机制找到具体的页。具体流程如下:
- 逻辑地址到段页地址的转换
- 逻辑地址由段号和段内偏移量组成
- 通过段表(Segment Table)查找段号对应的段基地址和段长度,验证段内偏移量是否在段长度范围内
- 段内地址到物理地址的转换
- 段基地址和段内偏移量相加得到段内地址
- 段内地址再分为页号和页内偏移量,通过页表查找页号对应的页框号
- 页内偏移量加页框号得到物理地址
- 最终的物理地址由页框号和页内偏移量组成
总结
分段(Segmentation)
优点
- 逻辑单元管理:每个段可以表示一个逻辑单元(如代码段、数据段、堆栈段),有助于程序结构化
- 灵活的大小:段的大小是可变的,可以根据实际需要进行分配,减少内存浪费
- 内存保护:可以为不同段设置不同的访问权限,增强内存保护和进程隔离
缺点
- 外部碎片:段的大小可变,容易产生外部碎片,导致内存空间利用率下降
- 复杂的内存管理:需要维护段表和段的动态分配,增加了内存管理的复杂性
分页(Paging)
优点
- 消除外部碎片:内存被分为固定大小的页,避免了外部碎片问题
- 简化内存管理:固定大小的页使得内存分配和回收更加简单
- 虚拟内存支持:分页机制与虚拟内存技术结合,可以高效地管理大地址空间
缺点
- 内部碎片:由于页的大小固定,可能会产生内部碎片,即未用完的页内空间浪费
- 地址转换开销:虚拟地址到物理地址的转换需要通过页表查找,增加了访问内存的时间开销
- TLB 未命中开销:TLB 未命中时,需要访问页表,增加了内存访问延迟
段页式内存管理(Segmented Paging)
优点
- 灵活的内存管理:结合了分段的逻辑单元管理和分页的固定大小页管理,提供了更灵活的内存管理
- 减少外部碎片:分页机制消除了外部碎片,同时保留了分段的逻辑结构优势
- 强大的内存保护:分段机制提供了细粒度的访问控制,增强了内存保护
缺点
- 实现复杂性:需要维护段表和页表,增加了实现和管理的复杂性
- 地址转换开销:地址转换过程更复杂,需要多次查找(段表和页表),增加了时间开销
- 硬件支持要求高:需要复杂的硬件支持(如 MMU,内存管理单元),增加了系统实现难度
目前操作系统的内存管理方案
现代操作系统大多采用分页(Paging)或段页式内存管理(Segmented Paging),具体选择取决于系统的需求和设计目标。
分页(Paging)
- 使用系统:Linux、Windows、macOS 等大多数现代操作系统
- 原因:分页提供了较好的内存利用率和简化的内存管理,适合于大多数通用计算环境。分页与虚拟内存技术结合,能够高效管理大地址空间
段页式内存管理(Segmented Paging)
- 使用系统:一些高级的操作系统和特定领域的系统(如某些实时操作系统)
- 原因:段页式内存管理结合了分段和分页的优点,适合需要复杂内存管理和高性能的应用环境。它在提供灵活内存管理的同时,增强了内存保护和隔离能力
- 分段适用于需要逻辑结构化和内存保护的场景,但易产生外部碎片
- 分页提供了简化的内存管理和较好的内存利用率,但易产生内部碎片和增加地址转换开销
- 段页式内存管理结合了两者的优点,提供了灵活和高效的内存管理,但实现复杂性较高
- 现代操作系统多采用分页或段页式内存管理,以满足不同应用需求和系统性能要求
参考资料
- 为什么要有虚拟内存?
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/135914.html