虚拟内存(地址)和物理内存(地址)、用户空间和系统空间、页面缓冲池和非页面缓冲池

整理参考资料:文档1文档2

1、几个重要的概念

物理地址(physical address) 
用于内存芯片级的单元寻址,与处理器和CPU连接的地址总线相对应。 
可以直接把物理地址理解成插在机器上那根内存条本身,把内存看成一个从0字节一直到最大空量逐字节的编号的大数组,然后把这个数组叫做物理地址


虚拟内存(virtual memory) 
对整个内存的抽像描述,它是相对于物理内存来讲的,可以直接理解成“不直实的”,“假的”内存。

为什么会出现虚拟内存:
是因为现代操作系统都提供了一种内存管理的抽像,即虚拟内存(virtual memory)。进程使用虚拟内存中的地址,由操作系统协助相关硬件,把它“转换”成真正的物理地址。 这样的抽像,一个程序,就可以使用比真实物理地址大得多的地址空间。(拆东墙,补西墙,银行也是这样子做的),甚至多个进程可以使用相同的地址。不奇怪,因为转换后的物理地址并非相同的。

逻辑地址(logical address) 
Intel为了兼容,将远古时代的段式内存管理方式保留了下来。


线性地址(linear address)或也叫虚拟地址(virtual address) 
跟逻辑地址类似,它也是一个不真实的地址,如果逻辑地址是对应的硬件平台 段式内存管理 转换前地址的话,那么线性地址则对应了硬件 页式内存管理 的转换前地址。


CPU将一个虚拟内存空间中的地址转换为物理地址,需要进行两步:
逻辑地址-->线性地址-->物理地址
首先将给定一个逻辑地址(其实是段内偏移量),CPU要利用其段式内存管理单元,先将为个逻辑地址转换成一个线性地址,再利用其页式内存管理单元,转换为最终物理地址。


用户空间和系统空间
在 32 位 Windows 中,可用的虚拟地址空间共计为 2^32 字节(4 GB)。 通常较下的 2 GB 用于用户空间,较上的 2 GB 用于系统空间。
                             

用户模式下运行的代码可以访问用户空间,但不能访问系统空间。 此限制可防止用户模式代码读或更改受保护的操作系统数据结构。

在内核模式下运行的代码可以访问系统空间和当前用户模式进程的虚拟地址空间。

页面缓冲池和非页面缓冲池
在用户空间中,所有物理内存页面都可以根据需要进行分页至磁盘文件。
在页面缓存池中分配的内存可以根据需要分页至磁盘文件。 在非页面缓冲池中分配的内存永远无法分页至磁盘文件。
                   

2、虚拟地址访问内存的几个优势:

总览:当处理器读或写入内存位置时,它会使用虚拟地址。作为读或写操作的一部分,处理器将虚拟地址转换为物理地址。通过虚拟地址访问内存有以下优势:
(1)程序可以使用一系列相邻的虚拟地址来访问物理内存中不相邻的大内存缓冲区。
(2)程序可以使用一系列虚拟地址来访问大于可用物理内存的内存缓冲区。当物理内存的供应量变小时,内存管理器会将物理内存页(通常大小为 4 KB)保存到磁盘文件。数据或代码页会根据需要在物理内存与磁盘之间移动。
(3)不同进程使用的虚拟地址彼此隔离。一个进程中的代码无法更改正在由另一进程或操作系统使用的物理内存。

举例:进程可用的虚拟地址范围称为该进程的“虚拟地址空间”。每个用户模式进程都有其各自的专用虚拟地址空间。 对于 32 位进程,虚拟地址空间通常为 2 GB,范围从 0x00000000 至 0x7FFFFFFF。对于 64 位进程,虚拟地址空间为 8 TB,范围从 0x000'00000000 至 0x7FF'FFFFFFFF。

                    

该图显示了两个 64 位进程的虚拟地址空间:Notepad.exe 和 MyApp.exe。每个进程都有其各自的虚拟地址空间,范围从 0x000'0000000 至 0x7FF'FFFFFFFF。每个阴影框都表示虚拟内存或物理内存的一个页面(大小为 4 KB)。注意,Notepad 进程使用从 0x7F7'93950000 开始的虚拟地址的三个相邻页面。但虚拟地址的这三个相邻页面会映射到物理内存中的非相邻页面。而且还注意,两个进程都使用从 0x7F7'93950000 开始的虚拟内存页面,但这些虚拟页面都映射到物理内存的不同页。



3、CPU的页式内存管理

CPU的页式内存管理单元,负责把一个线性地址,最终翻译为一个物理地址。
例如一个32位的机器,线性地址最大可为4G,可以用4KB为一个页来划分,这页,整个线性地址就被划分为一个tatol_page[2^20]的大数组,共有2的20个次方个页(存储格式为分页单元结构)。
分页单元结构:
             
(1)分页单元中,页目录是唯一的,它的地址放在CPU的cr3寄存器中,是进行地址转换的开始点。万里长征就从此长始了。 
(2)每一个活动的进程,因为都有其独立的对应的虚似内存(页目录也是唯一的),那么它也对应了一个独立的页目录地址。——运行一个进程,需要将它的页目录地址放到cr3寄存器中,将别个的保存下来。 
(2)每一个32位的线性地址被划分为三部份, 面目录索引(10位):页表索引(10位):偏移(12位) 

依据以下步骤进行转换: 
(1)从cr3中取出进程的页目录地址(操作系统负责在调度进程的时候,把这个地址装入对应寄存器); 
(2)根据线性地址前十位,在数组中,找到对应的索引项,因为引入了二级管理模式,页目录中的项,不再是页的地址,而是一个页表的地址。(又引入了一个数组),页的地址被放到页表中去了。 
(3)根据线性地址的中间十位,在页表(也是数组)中找到页的起始地址; 
(4)将页的起始地址与线性地址中最后12位相加,得到最终我们想要的葫芦;


猜你喜欢

转载自blog.csdn.net/yuewei19/article/details/80310236