虚拟内存页面替换

时间:2012-03-19 15:22:45

标签: memory-management operating-system x86 kernel

众所周知,当所有帧都已满时,有些页面需要在分页需求中被替换。但是,页面可以用作文本,rodata,数据,这些都是从磁盘I / O调用的,但是页面这样的堆栈,程序的堆只分配在内存中,磁盘中没有副本。我想知道堆栈和堆的页面是否涉及页面替换,如果是这样,它们是否应暂时交换到磁盘中?否则,它们应该固定在内存中吗?也许这个问题与具体实施密切相关,可以采用不同的策略,但我很想知道通常的做法。

2 个答案:

答案 0 :(得分:5)

所有用户模式页面都可以从RAM中删除。未经修改且由磁盘上的实际数据支持的页面(例如DLL和EXE的可执行文件和只读部分)将被简单地从内存中删除并重新请求页面。所有其他页面都写入页面文件并请求页面返回这包括堆栈,堆和VirtualAlloc内存。

靠近活动线程的堆栈内存往往不会被分页,因为它最近已被访问过,因此被分页守护进程/ APC分页出来是一个糟糕的选择,但这些页面远远超出了callstack和on经常被暂停的线程被系统分页,并且肯定没有固定在内存中。

唯一的一般例外是内核堆栈。每个核心必须至少有一个永不被页面调出的内核堆栈,否则页面错误会导致处理器出现三重故障并且核心会重新启动。

此外,Linux和Windows都有一个"非分页池"的概念,它是永远不会被分页的堆内存。这与" paged-pool"形成鲜明对比。根据需要由分页守护进程分页并进入的内存。 (此"非分页"内存需要服务页面故障守护程序本身,核心系统服务和服务,这些服务是分页守护程序工作所必需的,例如文件系统驱动程序,内存管理器等等)

答案 1 :(得分:2)

这就是您需要交换或分页文件的原因。如果您的页面是脏的(内存中的副本已被修改)但是很长时间没有被访问过,那么您可以使用它们占用的物理内存以获得更有用的东西的唯一方法是首先将它们写入磁盘

干净的页面(只包含零,没有人可以关心的数据或存储在磁盘上的文件副本)可以简单地从内存中丢弃,然后用于其他目的。

通常,固定在内存中的唯一页面是内核使用的页面或由特权进程固定的页面。许多内核函数暂时将内容固定在内存中,以便它们可以访问它们而不用担心页面错误。在内核返回用户空间之前,这些页面将被取消固定。

这是一个通用的答案,应该同样适用于所有主流的现代通用操作系统。