物理内存通过结构体vm_page_t以页为基础进行管理。 物理内存的页由它们各自对应的结构体vm_page_t所代表, 这些结构体存放在若干个页管理队列中的一个里面。
一页可以处于在线(wired)、活动(active),去活(inactive)、缓存(cache)、 自由(free)状态。除了在线状态,页一般被放置在一个双向链表队列里, 代表了它所处的状态。在线页不放置在任何队列里。
FreeBSD为缓存页和自由页实现了一个更为复杂的页队列机制, 以实现对页的分类管理。每一种状态都对应着多个队列, 队列的安排对应着处理器的一级、二级缓存。当需要分配一个新页时, FreeBSD会试图把一个按一级、二级缓存对齐的页面分配给虚拟内存对象。
此外,一个页可以有一个引用计数,可以被一个忙计数锁定。 虚拟内存系统也实现了“终极锁定”(ultimate locked)状态, 一个页可以用页标志PG_BUSY表示这一状态。
总之,每个页队列都按照LRU(Least-Recently Used)的原则工作。
译者注: 短语Least-Recently Used有两种理解方式: 1.将“least-recently”理解为反向比较级,意义为“最早”,整个短语理解为 “最近的使用时间最早”;2.将“least”和“recently”理解为副词, 都修饰“used”,整个短语理解为“最近最少使用”。 这两种理解方式的实际意义基本相同。
如果一个进程试图访问一个不在页表中而在某一队列中的页 (例如去活队列或缓存队列),一个相对耗费资源少的页错误发生, 导致页被重激活。如果页根本不存在于系统内存之中,进程必须被阻塞, 此时页被从磁盘中载入。
译者注: Intel等厂商的CPU工作在保护模式时,可用来实现虚拟内存。 当寻址的地址空间对应着真实内存时,则正常读写; 当寻址的地址空间没有对应的真实内存时,CPU会产生一个“错误”, 通知操作系统与磁盘等设备进行交换,读寻址则调入存储内容, 写寻址则写出存储内容。这个“错误” 并非操作系统或应用程序开发人员犯下的错误, 尽管在CPU硬件实现中这与应用程序或操作系统内核崩溃的错误的发生机制相同。 参见Intel的CPU保护模式开发手册。
FreeBSD动态的调整页队列,试图将各个队列中的页数维护在一个适当的比例上, 同时管理程序崩溃的已清理和未清理页。重新平衡的比例数值决定于系统内存的负担。 这种重新平衡由pageout守护进程实现,包括清理未清理页(与他们的后备存储同步)、 监视页被引用的活跃程度 (重置它们在LRU队列中的位置或在不同活跃程度的页队列间移动)、 当比例不平衡时在队列间迁移页,如此等等。 FreeBSD的VM系统会将重激活页而产生的错误频率调低到一个合理的数值, 由此确定某一页活跃/闲置的实际程度。 这可以为更好的决定何时清理/分配一个页做出决策。
本文档和其它文档可从这里下载:ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.
如果对于FreeBSD有问题,请先阅读文档,如不能解决再联系<questions@FreeBSD.org>.
关于本文档的问题请发信联系 <doc@FreeBSD.org>.