当计算机运行时,某个时间段内,它只是使用了一小部分的数据。其他数据在一个时间段内并不会被使用。

如果以整个程序为单位进行映射,会把不需要的数据读取到内存中,也会把过多的数据写入到磁盘,这种情况会降低程序的运行效率。

为解决这个问题,就有了内存的分页机制,使用分页的方式来对虚拟空间和物理空间进行分割和映射,提高程序的运行效率。

分页的思想是指把地址空间人为地分成大小相等的若干份,一份称为一页,就像一本书由很多页面组成,每个页面大小相等。也就是说内存条可以看为一本书,里面的物理内存被分为一页一页来管理,以页为单位对内存进行换入换出。即:

  • 当程序运行时,只需要将必要的数据从磁盘读取到内存,暂时用不到的数据先留在磁盘中,什么时候用到什么时候读取。
  • 当物理内存不足时,只需要将原来程序的部分数据写入磁盘,腾出足够的空间即可,不用把整个程序都写入磁盘。


页的大小
页的大小是固定的,由硬件决定,或硬件支持多种大小的页,由操作系统选择决定页的大小。比如 Intel Pentium 系列处理器支持 4KB 或 4MB 的页大小,那么操作系统可以选择每页大小为 4KB,也可以选择每页大小为 4MB,但是在同一时刻只能选择一种大小,所以对整个系统来说,也就是固定大小的。

例如:假设我们使用的PC机是32位的,那么虚拟地址空间总共有 4GB,按照 4KB 每页分的话,总共有 **2^32 / 2^12 = 2^20 = 1M = 1048576 个页(1G为2^30);**物理内存也是同样的分法。

根据页进行映射
通过一个简单的例子来说明虚拟地址是如何根据页来映射到物理地址的

如图所示:

内存分页组件 java 内存分页算法_数据

·  Program1和Program2的虚拟空间都有8个页(VP0----VP7),为了方便说明问题,我们假设每页大小为 1KB,那么虚拟地址空间就是 8KB。假设计算机有13条地址线,即拥有 2^13 的物理寻址能力,那么理论上物理空间可以多达 8KB(1kB=2^10)。但是出于种种原因,购买内存的资金不够,只买得起 6KB 的内存,所以物理空间真正有效的只是前 6KB。
·  当我们把程序的虚拟空间按页分隔后,把常用的数据和代码页加载到内存中,把不常用的暂时留在磁盘中,当需要用到的时候再从磁盘中读取。上图中,我们假设有两个程序 Program 1 和 Program 2,它们的部分虚拟页面被映射到物理页面,比如 Program 1 的 VP0、VP1 和 VP7 分别被映射到 物理内存PP0、PP2 和 PP3;而有部分却留在磁盘中,比如 VP2、VP3 分别位于磁盘的 DP0、DP1中;另外还有一些页面如 VP4、VP5、VP6 可能尚未被用到或者访问到,它们暂时处于未使用状态。图中的线表示映射关系,可以看到,Program 1 和 Program 2 中的有些虚拟页被映射到同一个物理页,这样可以实现内存共享。
·  这里,我们把虚拟空间的页叫做虚拟页(VP,Virtual Page),把物理内存中的页叫做物理页(PP,Physical Page),把磁盘中的页叫做磁盘页(DP,Disk Page)。

·  Program 1 的 VP2、VP3 不在内存中,但是当进程需要用到这两个页的时候,硬件会捕获到这个消息,然后操作系统接管进程,负责将 VP2 和 PV3 从磁盘中读取出来并且装入内存,然后将内存中的这两个页与 VP2、VP3 之间建立映射关系。


Code your future.