[MIT 6.S081] Lec 17: Virtual memory for applications 笔记

Lec 17: Virtual memory for applications

概述

用户应用程序也应该可以使用虚拟内存. 需要该特性的几种应用程序, 包括垃圾收集器, 数据压缩应用程序以及共享虚拟内存(SVM, Shared Virtual Memory)程序等.

应用程序使用虚拟内存所需要特性

  • Trap: 需要 Trap 使得发生在内核中的 page fault 传播的用户空间, 使用用户空间的处理程序(handler)处理相应的 page fault, 再返回内核并恢复指令执行.
  • Prot1: 降低一个内存页面的访问权限. 如将页面由读写变为只读.
  • ProtN: 管理多个页面的访问权限, 等效于调用 N 次 Prot1. 可以将开销分摊到 N 个页面. 而且只需要清除 1 次 TLB(而非 N 次), 减少了清除 TLB 的次数.
  • Unprot: 增加内存页面的访问权限
  • dirty: 返回上次调用以来的脏页.
  • map2: 使得应用程序可以将一个特定的内存地址空间映射两次, 且可以用于不同的访问权限.

Unix 支持应用程序使用虚拟内存的系统调用

  • mmap(addr, len, prot, flags, fd, off): 接受某个对象将其映射到调用者的地址空间. 该系统调用还可以用来映射匿名内存(Anonymous Memory). - 可以通过多次调用实现 map2 特性
    • addr: 映射到的地址. NULL 表示不指定特定地址.
    • len: 映射的地址长度
    • prot: 映射地址的访问权限, 如 R|W
    • flags: 标志位
    • fd: 传入的对象(描述符)
    • off: 偏移
  • mprotect(addr, len, prot): 修改对虚拟内存的权限. - 对应 Prot1, ProtN, Unprot 特性
  • munmap(): 移除一个地址或一段内存地址的映射.
  • sigaction(): 用于处理信号(signal), 调用对应的处理函数. Page fault 场景下对应 segfault 信号. - 对应 trap 特性

应用程序使用虚拟内存的实现

虚拟内存实现

地址空间由页表体现, 地址空间还包括一些操作系统的数据结构, 称之为虚拟内存区(Virtual Memory Areas, VMAs).
VMAs 记录有关连续虚拟内存段的信息. 地址空间中包含多个段(section), 每个段地址空间连续, 有一个 VMA 对象, 对应地址空间有相同权限.

用户级 trap

  1. PTE 被标记为无效或只读, 此时需要向其对应页面写数据
  2. CPU 跳转到内核的固定程序地址(如 XV6 中的 trampoline 代码), 内核会保存应用程序的状态(XV6 中保存到 trapframe).
  3. 向虚拟内存系统查询处理方法
  4. 在用户级 trap, 且设置了 segfault 的处理程序, 则会向上调用进入用户空间
  5. 运行处理函数, 如 mprotect()
  6. 处理函数执行完后返回到内核
  7. 内核恢复中断的进程

实例

构建大的缓存表

在内存中构建一个缓存表记录复杂计算的值, 后续可以直接访问缓存表获得结果而非重新计算.
初始使用 mmap 系统调用映射一个页面, 并立即是否这页虚拟内存.
当需要访问缓存表时发送缺 segfault 信号, 由 sigaction 设置的处理函数, 通过 mmap 一个物理页并对整个页面中所有的表单项计算.
后续若访问的值在缓存表中则直接返回, 不在表中则同样触发处理函数, 将原映射的页面 munmap 取消映射, 同时重新 mmap 一个物理页, 并计算该物理页的中所有的表单项.
通过应用程序使用虚拟内存, 使得对于一个大的缓存表, 可以只使用 1 个页面, 而通过处理函数进行缓存表项的更替, 而应用程序则不会直接感知到.

Baker’s Real-Time Copying Garbage Collector

不使用虚拟内存

一种增量 GC (incremental GC), 内存空间包含 from 和 to 两个空间.
GC 过程时不停止程序运行并将所有对象从 from 空间拷贝到 to 空间, 然后恢复程序运行. 而是只扫描几个对象将其从 from 空间拷贝到 to 空间(该过程成为 forward).
若应用程序调用 new 申请内存, 则再扫描几个对象, 将对象从 from 空间拷贝到 to 空间.
每次获取一个对象的指针时(dereference), 需要检查对象是否在 from 空间, 是的话就需要将其拷贝到 to 空间(指针的跟踪需要在同一空间完成). 因此应用程序允许使用指针但需要对每个指针进行检测, 增加了应用程序开销.
当 GC 完成所有对象的跟踪后, 会清空 from 空间并重用.
该种情况不能容易并行运行 GC, 因为应用程序与 GC 可能会发生对对象的抢占.

使用虚拟内存

to 空间包含 scanned(已扫描)和 unscanned(未扫描)两部分页面. 对于应用程序, unscanned 部分的权限是 None, 对于 GC, 该部分的权限是可读写(此处将该部分物理内存映射两次, 即 map2 来进行不同权限的设置).
开始 GC 时将根结点(这里的根结点指的是会记录到栈上或者寄存器中的变量/指针/地址)拷贝到 to 空间的 unscanned 区域.
应用程序访问根结点由于 unscanned 区域权限是 None 因此会触发 page fault.
在 page fault 的处理程序中, GC 会将根结点所在的页面的所有对象进行跟踪, 将其指向的所有在 from 空间的对象都拷贝到 to 空间的 unscanned 区域, 并将根结点所在页面设置为 scanned, 并恢复该页面的权限.
后续操作类似, 当访问 scanned 区域的对象时正常运行, 访问 unscanned 区域时会发生 page fault, 再将页面中指向 from 空间的对象进行拷贝, 并将页面设置为 scanned.
内存的分配都是在 to 空间的 unscanned 区域完成的.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值