当前位置:嗨网首页>书籍在线阅读

03-页和页面调度

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

9.1.1 页和页面调度

内存是由比特位组成,8个比特组成一个字节。字节又组成字,字组成页。对于内存管理,页是最重要的:页是内存管理单元(MMU)可以管理的最小可访问内存单元。因此,虚拟空间是由许多页组成的。系统的体系结构以及机型决定了页的大小(页的大小是固定的),典型的页大小包括4K(32位系统)和8K(64位系统)[1]

32位地址空间包含约一百万的4KB的页,而64位的地址空间包含数倍的8KB的页。一个进程不可能访问所有这些页,这些页可能并没有任何含义。因此,页有两种状态:无效的(invalid)和有效的(valid),一个有效页(valid page)和实际的数据页相关联,可能是物理内存(RAM),也可能是二级存储介质,比如交换分区或硬盘上的文件。一个无效页(invalid page)没有任何含义,表示它没有被分配或使用。访问一个无效的页会引发一个段错误。

地址空间不需要是连续的。虽然是线性编址,但实际上中间有很多未编址的小区域。

如果一个有效的页和二级存储的数据相关,进程不能访问该页,除非把这个页和物理内存中的数据关联。如果一个进程要访问这样的页,那么存储器管理单元(MMU)会产生页错误(page fault)。然后,内核会介入,把数据从二级存储切换到物理内存中(paging in),而且对用户“透明”。由于虚拟内存要比物理内存大得多,内核可能需要把数据从内存中切换出来,从而为后面要Page in的页腾出更多空间。因而,内核也需要把数据从物理内存切换到二级存储,这个过程称为Paging out。为了优化性能,实现后续page in操作代价最低,内核往往是把物理内存中近期最不可能使用的页替换出来。

共享和写时复制

虚拟内存中的多个页面,甚至是属于不同进程的虚拟地址空间,也有可能会映射到同一个物理页面。通过这种方式,可以支持不同的虚拟地址空间共享物理内存上的数据。举个例子,在某个时刻,系统中的很多进程很可能是使用标准C库。有了共享内存,这些进程可以把库映射到它们的虚拟地址空间,但是在物理内存中只存在一个进程。举个更明显的例子,两个进程可能会映射到大数据库的内存中。虽然这两个进程的数据库都在其虚拟地址空间中,它们只存在于RAM中。

共享的数据可能是只读的,只写的,或者可读可写的。当一个进程试图写某个共享的可写页时,可能发生以下两种情况之一。最简单的是内核允许写操作,在这种场景下,所有共享这个页的进程都将看到这次写操作的结果。通常,允许大量的进程对同一页面读写需要某种程度上的合作和同步机制。但是在内核级别,写操作“正常工作”,共享数据的所有进程会立即看到修改。

在另一种情况场景下,内存管理单元(MMU)会拦截这次写操作,并产生一个异常。内核会相应地“透明”创建一份该页的拷贝,支持继续对新的页面执行写操作。我们将这种方法称为“写时拷贝(copy-on-write)(COW)”[2]。实际上,允许进程读取共享的数据,这样可以有效节省空间。当一个进程想要写一个共享页面时,可以立刻获得该页的唯一拷贝,这使得内核工作起来就像每个进程都始终有它自己的私有拷贝。写时拷贝是以页为单位进行的,通过这种方式,多个进程可以高效共享一个大文件。每个进程只有在对共享页写时才能获得一份新的拷贝。