0

在使用虚拟内存的操作系统中,每个进程都有一个页表。每个页表将进程的虚拟内存页映射到系统的物理内存页,并指示给定页当前是否有效(加载到内存中)。

假设内存运行不足,操作系统需要选择一个页面从物理内存中逐出。为此有不同的算法。例如,先进先出、LRU。一旦操作系统选择要驱逐的页面,它如何使对该页面的任何现有引用无效?

如果活动进程当前正在使用受害页面,则操作系统必须使当前进程的页表中的映射无效。如果受害者页面当前被另一个进程使用,操作系统必须使其他进程的页表中的映射无效。无论如何,操作系统如何确定要更新哪个页表(如果有),以及它如何知道映射在该页表中的位置而不进行线性搜索?

从本演示文稿的幻灯片 22 开始,详细描述了 x86 页表结构:

http://www.scs.stanford.edu/12au-cs140/notes/l8.pdf

我还发现了一些有用的虚拟内存概述:

http://www.cs.uic.edu/~jbell/CourseNotes/OperatingSystems/9_VirtualMemory.html http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Memory/virtual.html

没有答案的类似 Stack Overflow 问题:

上下文切换后linux如何更新页表

4

2 回答 2

2

实际上,您要问的事情称为反向映射。例如,在 Linux 中,您可以找到有用的函数try_to_unmap_anon在页面描述符中有一个称为映射的字段。该字段是匿名页面anon_vma。如您所见,这不仅是普通的结构,而且还是一个列表条目。一页可能有多个 anon_vmas(请参阅 try_to_unmap_anon):

list_for_each_entry(vma, &anon_vma->head, anon_vma_node)

每页映射正好一个。所有这些 vmas 都链接到列表中。这就是内核如何知道哪些进程(及其页表)正在运行。现在关于内核如何确定虚拟地址......再次可以在这里找到答案:vma_address

233         pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
234         unsigned long address;
235 
236         address = vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT);

所以我们现在可以很快回答你的问题:为了不进行页表扫描,内核将它需要的所有内容(用于快速获取)存储在页描述符(struct page)中。

于 2015-07-09T18:59:13.917 回答
1

通常操作系统会选择一个进程首先要减少内存。然后它将从该过程中选择页面。然后它知道要使用的页表。

您建议选择一个页面然后查找哪个进程。这通常发生在具有可分页内核的系统中。在这种情况下,系统页表由所有进程共享。

于 2015-07-10T00:30:31.177 回答