Windows内存管理知识总结
本篇文章主要是理解32位Windows操作系统下的虚拟地址到物理地址的映射。
首先我们对Windows的内存管理机制做简要介绍。
Windows为每个进程分配了4GB的虚拟地址空间,让每个进程都认为自己拥有4GB的内存空间。
然后Windows系统把这4GB大小的空间划分为进程和系统两个部分,每个进程可以获得2GB的虚拟内存,根据可用的容量。分配给所有进程的虚拟内存总数不能超过页面文件和大多数物理内存的总和(操作系统本身也要占据一小部分物理内存)。
每个进程的4G内存空间只是虚拟内存空间,每次访问内存空间的某个地址,都需要把地址翻译为实际物理内存地址
所有进程共享同一物理内存,每个进程只把自己目前需要的虚拟内存空间映射并存储到物理内存上。
下面我们就进行讨论,Windows操作系统下的虚拟地址到物理地址是如何进行映射。
进程被创建时会建立一个 虚拟内从到物理内存的映射表--------页表,根据页表可以将虚拟内存和物理内存关联起来
内存的分页
内存映射要通过页表,首先我们思考为什么要进行分页处理?
当程序运行时,进程需要从内存中读出这段程序的代码。代码的位置必须在物理内存中才能被运行,由于操作系统中有非常多的程序运行着,内存中不可能够完全放下所有的物理页面,所以引出了虚拟内存的概念。
把哪些不常用的程序片断就放入虚拟内存,当需要用到它的时候在load入主存(物理内存)中。这个就是内存管理所要做的事。内存管理还有另外一件事需要做:计算程序片段在主存中的物理位置,以便CPU调度。
这个调度就是利用内存分页,通过页表映射的。
Win32通过一个两层的表结构来实现地址映射
第一层称为页目录,实际就是一个内存页,Win32的内存页有4KB大小,这个内存页以4个字节分为1024项,每一项称为“页目录项”(PDE);
第二层称为页表,这一层共有1024个页表,页表结构与页目录相似,每个页表也都是一个内存页,这个内存页以4KB的大小被分为1024项,页表的每一项被称为页表项(PTE),易知共有1024×1024个页表项。每一个页表项对应一个物理内存中的某一个“内存页”,即共有1024×1024个物理内存页,每个物理内存页为4KB,这样就可以索引到4G大小的虚拟物理内存。
实际的过程也就是CR3->页目录项->页表项->内存页->偏移=物理地址
当然了,上面的假设的前提是此数据已在物理内存中。
当访问数据已经在物理内存中时,按照上面步骤进行地址映射,然后对数据进行访问。
如果当前数据不在物理页面的话就要抛出缺页中断,然后判断数据是否在页交换文件中?
如果不在则访问违例,程序将会退出,如果在,页表项会查出此数据页在哪个调页文件中,然后将此数据页调入物理内存,再继续进行地址映射。
了实现每个进程拥有私有4G的虚拟地址空间,也就是说每个进程都拥有自己的页目录和页表结构,对不同进程而言,即使是相同的指针(虚拟地址)被不同的进程映射到的物理地址也是不同的,这也意味着在进程之间传递指针是没有意义的。
参考:
《Windows核心编程》