前言
本文为学习虚拟内存时的学习总结。如有错误,欢迎指正。
正文
源代码经过编译和链接后会生成一个可执行目标文件,这里再次贴出这个可执行目标文件的结构图:
详情见:总结--链接器的工作原理
页表
cpu如何将虚拟地址映射到真实地址的呢?计算机将虚拟地址等分成固定大小的页(比如说64KB),每个页由一个页条目表示,从而形成一个页表, 我们以程序加载为例:
通过这样的一个模型,大大减轻了加载器的工作压力。加载也变成了一个看似很轻松的工作。这样子的模型看似可以良好的运行,可是却难免会遇到一个情况,假设我们现在仅有4G主存,而且假设4G空间都被占用了。现在一个程序申请4KB的空间,怎么办?计算机可能会想:"哦豁!完犊子,没空间了,直接报异常吧!"。通常情况还有另外一种解决办法,操作系统允许在磁盘上配置一定空间拓展主存(称为虚拟主存),这时操作系统会在主存中挑选一个或多个页调出主存,存储到虚拟主存中,修改对应的页表条目将其状态置为未缓存,并修改指针指向对应的磁盘地址。当程序再访问到这个页时再从磁盘调入主存。
- 通过这样的一种模型,每个进程都拥有一个自己完全独立的地址空间,大大简化了多进程申请内存时地址分配的复杂性。
- 通过这样一种模型,主存充当了磁盘的缓存,这也许跟我们之前讨论的L1,L2高速缓存有点类似。但是他们存在一个很大的不同,高速缓存与主存的缓存块是根据地址来映射的,他们之间的对于关系非常绝对,处理缓存冲突也是十分绝对的将冲突的块刷新回主存。但是虚拟内存的虚拟页在主存和磁盘中的映射关系并不是根据地址一一对应的,他是由一个额外的页表来维护。也就是说仅当主存占满后才会出现空间分配不足的,并且处理这种情况也不是绝对的选取一个映射页调出主存,确定调出那个页取决于操作系统的页面调度算法。