概述
- 为什么需要虚拟内存技术
- 解决进程间的地址空间隔离问题,因为如果直接对物理地址进行操作,假设有两个进程,就可能会不小心访问到对方的物理地址,进行操作,使另一个进程崩溃掉。
- 我们可以使用虚拟内存技术,为每个进程独立的划分一块虚拟内存,而虚拟内存会与物理内存建立起一种映射关系,而程序员也只需要关心这块虚拟内存,不用关心实际的物理内存。
如图,两者是一一映射的。
- 这里的虚拟内存并非真实存在的,进程所拥有的虚拟地址会通过 CPU 芯⽚中的内存管理单元MMU中的映射关系,来将其转换变成物理地址,然后再通过物理地址访问真实的内存。
- 操作系统通过内存分段和内存分页来管理虚拟地址和物理地址。
内存分段
- 如何进行内存的分段
- 一个进程可由多个不同的属性的内存的段组成,这其中包括代码分段、数据分段、栈段、堆段。
- 虚拟地址和物理地址通过段表映射起来,每一个由两个部分组成,段选择子(保存在段寄存器中)和段内偏移量。CPU通过这两个元素,可以由虚拟地址得到物理地址。
- 内存分段存在什么问题
- 内存碎片
- 由于对于每个进程是一整段一整段的分配内存,内存中间可能产生不连续的小内存,而这些小内存的碎片化致使无法有整块的内存,应对新的进程的需要。
- 可以通过内存交换来解决,将一些进程占用的内存,写回到磁盘,再装回内存之中,但是装回的时候不在原来的位置,而是和其他使用的内存紧挨着,来去除碎片化的内存。但由于内存分段极容易产生碎片化的内存,每次这样的操作,导致效率低。如过交换的内存很大,效率更低。
- 内部内存浪费
- 每次都把程序所有的内存都装载进来,但是有部分的内存并不经常使用,却一直占有着有限的资源,这就会导致内存的浪费。
- 内存碎片
内存分页
- 分页是指将物理内存和虚拟内存都划分成了大小相等的空间,每一个我们称之为页。在Linux中每一页的大小为 4KB 。内存分页和内存分段大概相同,它也是通过一个页表(存储在页表寄存器)来找到对应的物理内存。
- 内存分页如何解决上述两个问题
- 内存分页并不会产生间隙小的内存,因为内存已被预先划分好,释放的内存也是以页为单位,不会产生无法给进程使用的小内存。
- 如果内存空间不够,可以将最近使用少的的内存页面释放掉,写入硬盘中。需要的时候再加载进来。每次写⼊磁盘的页数并不多,相比内存分段一段一段的交换,要更加高效。
- 内存分页是如何分页的
多级分页
- 为什么使用多级分页
- 因为我们需要给每个进程划分内存,而每个进程使用的页表必须涵盖了所有的内存的地址,否则当进程找不到地址时,就会停止运行。但由于操作系统运行的进程通常上百,每个进程都要存储完整的对应自己的页表,这样的存储内存对于有限的资源还是比较多的,这并不划算。
- 何为多级页表
如图,更多的级数也是如此 - 如何节省了内存
- 将一个页表划分成了两个,貌似也没有减少多少,但是我们所有的内存都能在一级页表被找到,而二级页表我们并不需要全部和一级页表对应起来,假设我们是32位的环境,每个进程对应的虚拟内存就是4G,我们的进程不会用到这么多,我们只需要在需要时将对应的二级页表创建起来就行了。
TLB
- 为什么需要TLB
- 多级分页带来了操作程序上的复杂,进而带来了效率的降低,加大了时间上的开销。而TLB即为CPU 芯片中,⼀个专门存放程序最常访问的页表项的Cache。它可以与MMU进行交互。CPU在寻址的时候,会先查询TLB,如果没有,才会再去查询一般的页表。
段页式内存管理
-
如何实现段页式内存管理
- 先将进程划分为多个段,然后再把每个段对应到一个页表上,也就是段被划分为多个页。
- 先将进程划分为多个段,然后再把每个段对应到一个页表上,也就是段被划分为多个页。
-
段页式管理是段式管理和页式管理相结合而成,具有两者的优点。
- 在这里,内存分段和内存分页一样都是一种内存管理技术,分段是为了权限保护,而分页才是为了虚拟内存.
- 分段后,程序员可以定义自己的段,各段有独立的地址空间
- 如果错误的访问了不同的段,会因为段保护而导致出错,这实现了对该段的保护。