CSAPP--第九章:虚拟内存

CSAPP:虚拟内存

虚拟内存介绍

  • 说明:

    为了更加有效地管理内存,并且少出错。现代系统提供了一种对主存的抽象概念,称为:虚拟内存(Virtual Memory:VM)

物理和虚拟寻址
  • 物理寻址(PA):

    使用对象:早期计算机系统,及某些小型嵌入式系统中。

    寻址方式:①将内存分为一个连续的数组,字节为单元,每个字节都包含了唯一的物理地址。②cpu直接发送物理地址到内存,找到该字节,读取并返回到cpu寄存器中。

    如下图:


    物理寻址抽象
  • 虚拟地址(VA):

    使用对象:现代计算机系统。

    寻址方式:①将内存分成连续的字节数组,并且构造了一张查询表。②cpu芯片上维护一个内存管理单元(MMU),cpu发送虚拟地址到MMU,其与操作系统协同进行翻译。③将翻译的地址,访问内存物理地址,读值并返回到cpu寄存器。

    如下图:

    虚拟寻址抽象
  • 地址空间:

    非负数整数地址的有序集合。

    线性地址空间:地址空间的整数是连续的。本章假设使用的是线性地址空间。

    虚拟地址空间:若地址空间包含N=2^n个地址,则可以称为n位地址空间。

    物理地址空间:对应于物理地址中的字节数M,可以不为2的幂,但本文假设为2的幂。

虚拟内存作为缓存

对应于cpu和主存间的高速缓存L1,L2,L3。主存和磁盘间的虚拟内存管理方式也类似。

如同高速缓存结构,磁盘中的数据也被分成固定大小的块,在磁盘和主存间进行数据传送。

物理内存被分为物理页(Physical Page:PP),虚拟内存也被分为虚拟页(Virtual Page:VP)。

  • 虚拟页:

其被组织为虚拟页的集合。包括三个不相交的子集:

①已缓存的:虚拟页指向物理页。

②未缓存的:虚拟页指向磁盘空间。

③未分配的:虚拟页为空。

如下图:

虚拟页作为缓存
  • 虚拟页的缓存机制:

    ①由于不命中处罚很严重(要访问磁盘,速度慢100K倍),DRAM缓存(虚拟页)全相连的。

    ②不命中的替换策略也很重要,操作系统使用了很精密复杂的替换算法。

    ③DRAM缓存使用写回,而不是直写。

页表

  • 说明:

    虚拟内存作为缓存机制,其功能由操作系统、MMU和物理内存中的页表共同实现。

    页表(PT)是一张存放了物理页号或磁盘地址的表。如下图,其中元素为页表词条PTE:包含有效位和物理页号(或磁盘地址)。

    如下图,形似高速缓存中的结构:

    页表
  • 页命中

    页命中流程抽象图
  • 缺页(页不命中)

    当发现缺页时,会调用异常处理机制,将磁盘上的对应页调入到内存,然后重新执行原指令。

下图为缺页前和缺页后:


缺页前
异常处理后(缺页后)
  • 页面分配过程

    页面分配过程

  • 实际效能

    由于局部性的关系,虚拟内存的工作性能相当乐观。

    程序总趋向于在一个较小的活动页集合上工作,称其为工作集。

    但当工作集大小超过物理内存大小时,可能会发生抖动。会严重阻碍程序性能。

    linux统计缺页:用getrusage函数。

用虚拟内存进行内存管理

  • 结构说明:

    虚拟内存对每个进程,维护了一个独立的虚拟页表。使之可以用一个通用的方法,来处理每一个进程。


    进程 i,j 的虚拟表示意图
  • 简化:

    • 简化链接:

      每个进程拥有独立地址空间,所以可以用相同格式,来链接代码和数据,而不管代码和数据实际存放的物理内存地址。如对每个64位机器中的进程,都可以看做从0x40000地址开始放置代码段、(对齐间隙)、数据段,堆、栈空间等。

    • 简化加载:

      当加载时,虚拟内存会给数据段和代码段分配虚拟页,标记为未被缓存的。

      但并不实际进行复制,而是当cpu初次调用指令时,才会加载到内存中。

    • 简化共享:

      对于共享目标文件和系统函数等,操作系统将不同进程中适当的虚拟页,映射到相同的物理页面,从而可以共享一个副本。

    • 简化内存分配:

      当分配了内存空间时,如调用malloc函数,操作系统会适当分配连续的k个虚拟页面,其可以不连续映射在物理页面中,而是可以随机分散。

虚拟内存机制提供内存保护

  • 说明:

    通过在每一条页表中,设置许可位,可以有效进行内存保护。

    SUP:是否在内核模式才可以访问。

    READ\WRITE:是否可以读、写。

    真实的系统中,其有更多的许可位来进行内存保护,包括对内存泄漏攻击的防护等。

    如下图:

  • 地址翻译符号小结图
地址翻译的符号总结
  • 使用页表进行地址翻译流程

    ①通过页表机制寄存器得到本进程页表数组的首地址

    ②用VPN(虚拟页表号)作为索引找到指定页表

    ③页命中的情况下:提取物理页表,并与VPO(虚拟页偏移量)合并成物理地址。

    //虚拟页和物理页的偏移量,就是页字节大小的偏移量。由于页大小固定,所以他们两个一样。

使用页表的地址翻译流程
  • 页面命中和缺页的流程

    说明:

    a)页面命中时,全程由硬件完成。

    b)缺页时,会调用操作系统中的异常处理程序,选择一个牺牲页,并从磁盘读取目的页。

命中和缺页的操作流程
  • 高速缓存与虚拟内存结合

    之前的示意图,高速缓存和内存是放在一个抽象模块中的。现在将他们分离开来。

    PTEA:页表词条的地址,即虚拟地址中的VPN。

    现代系统中,高速缓存是用物理寻址,由此可以直接得到指令和数据。

    PTEA通常是和TLB(翻译后备缓冲器)进行交互,得到页表中的物理页号(PPN)。

    如下图:

多级页表

  • 多级页表说明:

    因为内存的容量有限,如果将每个进程的全部页表都放在内存中,会很大的消耗内存,加之进程中大多数页表是空的,造成了内存浪费。

    多级页表便是采用多层映射的方式,是内存中常驻的非空一级页表,仅保存指向二级页表的基址。

    出于两个方面而使用多级页表:

    ①当典型的程序中,4G的虚拟地址空间大部分都是未分配的。对于空的PTE,其二级页表也不会存在,节约内存空间。

    ②只有一级页表才需要常驻在内存中。当需要二级页表时,如初次调用某函数,可以临时创建、调入二级页表。

注意:
1级页表和2级页表都包含1K(2^10)个虚拟页表词条PTE。
1级页表中,每个PTE大小是一个4M的片 = 1K个页 = 1K * 4K 个字节。

如下图:

2级页表示意图
  • k级页表的地址翻译

    将虚拟地址中的VPN(虚拟页表号),分为k分,作为每级页表的偏移量索引。

    如:VPN1会根据页表基址寄存器(PTBR),找到指定偏移量的页表词条:PTEx。PTEx又作为2级页表的基址,配合VPN2可以得到下一级的地址。

    如下图:


你可能感兴趣的:(CSAPP--第九章:虚拟内存)