图源自 小林coding
虚拟内存是什么?
虚拟内存是一种计算机系统管理内存的技术,它使操作系统能够将物理内存(RAM)和硬盘存储结合使用。虚拟内存的主要作用包括以下几点:
-
扩展物理内存的使用: 虚拟内存允许系统将硬盘上的部分空间(称为交换区或页面文件)作为扩展的内存来使用。当物理内存不足时,操作系统会将不常使用的内存页面(数据或程序代码的部分)从RAM中移到硬盘的交换区,这样可以释放更多的RAM给活跃的进程使用。
-
内存隔离和保护: 每个进程运行在自己的虚拟地址空间中,互相独立。这意味着一个进程无法直接访问其他进程的内存,从而提高了系统的安全性和稳定性。
-
提高内存管理效率: 虚拟内存通过分页(paging)或分段(segmentation)机制来实现内存的灵活管理,避免内存碎片的产生,并允许系统灵活地分配和回收内存。
简单来说,虚拟内存提高了系统的内存利用率和安全性,使得程序在运行时即便超出了物理内存的容量,系统依然能够继续运行。
内存分段机制
为什么有分段机制
程序是由若干个逻辑分段组成的,如可由代码分段、数据分段、栈段、堆段组成。不同的段是有不同的属性的,所以就有分段的形式把这些段分离出来。
虚拟地址和物理地址是如何映射的?
虚拟地址由两部分组成:段选择因子和段内偏移量。 段选择因子包括段号。
段表保存了段的基地址、段的界限等,虚拟地址中的段内偏移量应该在 0 和段界限之间,如果段内偏移量合法,那么物理内存地址就等于段基地址加上段内偏移量 。
缺点
1、外部内存碎片问题。 由于内存分段管理可以做到段根据实际需求分配内存,有多少需求就分配多大的段,所以不会出现内存内部碎片问题。但是假如两个不连续的段的内存被回收了,这两块内存无法合并成一个大的内存,所以会产生两个外部内存碎片。
2、内存交换效率低。 解决外部内存碎片的方法是内存交换。先将分隔内存碎片的程序占用的内存写道磁盘上,再从磁盘上读回内存,这样就能合并两个分开的内存碎片。但是由于磁盘的 IO 很慢,并且每次交换都需要将大段的内存写入读取,所以会使机器卡顿。
内存分页机制
为什么有内存分页机制
为了解决内存分段的外部内存碎片和内存交换效率低 的问题。要解决这些问题,那么就要想出能少出现一些内存碎片 的办法。另外,当需要进行内存交换的时候,让需要交换写入或者从磁盘装载的数据更少一点,这样就可以解决问题了。这个办法,也就是内存分页。
- 内存分页机制,页与页之间是紧密排列的,所以不会有外部碎片(但是如果程序不足一页,会产生内部碎片)。
- 如果内存空间不够,操作系统只会换出换入少量的页,不会花太多时间。
因此内存交换的效率就相对比较高。
虚拟地址和物理地址是如何映射的?
分页是把整个虚拟和物理内存空间切成一段段固定尺寸的大小。这样一个连续并且尺寸固定的内存空间我们叫页(Page)。在 Linux下,每一页的大小为4KB。
虚拟地址由页号和页内偏移量组成,虚拟地址与物理地址之间通过页表来映射,如下图:
对于一个内存地址转换,其实就是这样三个步骤:
- 把虚拟内存地址,切分成页号和偏移量;
- 根据页号,从页表里面,查询对应的物理页号,
- 直接拿物理页号,加上前面的偏移量,就得到了物理内存地址。
缺点
页表占用空间大。
32 位环境下,虚拟地址空间有 2^32 = 4GB,假设一个页的大小是 2^12 =4KB,那么就需要 2^20 = 1MB 个页,每个页需要 4B 存储,那么 4GB 空间的映射就需要有 4MB 的内存来存储页表。每个进程都有自己的页表,假设有 100 个进程就需要 400MB 的内存来存储页表,占用了很大的内存。
解决方式
多级页表。
把 1MB 个页表项再分页,将一级页表分为 1024 个二级页表,每个二级页表存储 1024 个页。
一级页表和二级页表结合起来能够覆盖全部虚拟地址空间。(页表一定要覆盖全部虚拟地址空间。)
如果某个一级页表的页表项没有用到,那么就不需要创建这个页表项对应的二级页表,也就省去了 1KB 个页的内存。
TLB。
多级页表虽然解决了空间上的问题,但是虚拟地址到物理地址的转换就多了几道转换的工序,这就带来了时间上的开销。由于程序空间局部性的存在,把最常访问的几个页表项存储到高速缓存(TLB,快表)中,加快了虚拟地址的转换。
段页式内存管理
- 先将程序划分为多个有逻辑意义的段,也就是前面提到的分段机制;
- 接着再把每个段划分为多个页,也就是对分段划分出来的连续空间,再划分固定大小的页,
这样,地址结构就由段号、段内页号和页内位移 三部分组成。
用于段页式地址变换的数据结构是每一个程序一张段表,每个段又建立一张页表,段表中的地址是页表的起始地址,而页表中的地址则为某页的物理页号,如图所示:
段页式地址变换中要得到物理地址须经过三次内存访问:
- 第一次访问段表,得到页表起始地址;
- 第二次访问页表,得到物理页号;
- 第三次将物理页号与页内位移组合,得到物理地址。
可用软、硬件相结合的方法实现段页式地址变换,这样虽然增加了硬件成本和系统开销,但提高了内存的利用率。