大纲
通过虚拟内存机制,我们可以做些很酷的特性:
- 延迟分配
- 更好的性能 2.1 共享零页 2.2 写时拷贝
- 新的特性: 3.1 内存映射文件
首要目的
- 我们使用虚拟内存的首要目的是为了让各进程用力独立的内存地址空间.
- 虚拟内存提供了一种间接访问物理内存的方式,使用这种间接方式,内核可以做些很酷的特性.
特性
按需分配(延迟分配)
- 当用户进程调用
sbrk()
并不实际分配内存,而是在真正使用到时再进程分配. - 具体内容在完成第六天的课后作业后,大家应该已经比较了解了.
共享零页
- 根据实际观察,一个用户进程申请内存后永远也不会写,并且这些内存常常都被初始化为0.
- 因此系统将一页物理内存初始化为0.在上面的情况中,所有用户进程将会共享这样一个零页.
- 如果用户进程需要写零页,将会触发page fault中断,届时再进行分配.
共享内核页表
- 所有用户进程都有自己的一级页表.同时所有用户进程都有相同的内核内存映射关系.
- 因此,在所有用户进程中关于内核内存映射的二级页表所对应的物理内存,可以在所有用户进程间共享.
栈保护页
- 在x86汇编层面,对于栈的边界是没有保护的.
- 利用虚拟内存机制,我们可以在栈的边界进行保护.
- 通过在内存中增加越界处理逻辑,还可以动态扩展栈的大小.
写时拷贝
- 在实际使用过程中,在
fork()
之后,经常立刻调用exec()
. - 因此在
fork()
时,往往没有必要将父进程物理页中的信息拷贝到子进程的物理页中. - 在
fork()
时,子进程共享父进程的物理页,同时将权限设置为只读. - 这样在
exec()
时将触发page fault
中断,此时再分配新的物理页,避免了无效的拷贝.
请求页面调度
- 目前
exec()
会将整个目标文件载入内存,而IO操作是比较慢的,而且整个文件往往不会都被使用. - 可以通过虚拟内存将文件映射到虚拟内存中,但并不实际载入物理内存.在实际需要使用时,通过处理
page fault
处理.
内存swap
- 通过将暂时用不到的物理内存置换到硬盘中,使得内核可以提供比实际物理内存还要大的内存空间
文件内存映射
- 通过读取文件是依靠函数
read()
,write()
,lseek()
- 系统调用
mmap()
可以直接将文件映射到虚拟内存空间,这样我们就可以通过地址偏移,而不是seek来读取文件.
分布式共享内存
- 通过网络,在不同计算机之间共享物理内存.