码迷,mamicode.com
首页 > 其他好文 > 详细

page fault

时间:2020-12-19 13:34:32      阅读:5      评论:0      收藏:0      [点我收藏+]

标签:and   来源   swap   developer   内存   dem   width   height   内存区域   

当我们向操作系统申请内存时,操作系统并不是直接分配给我们物理内存,而是只标记当前进程拥有该段内存,当真正使用这段段内存时才会分配。

这种延迟分配物理内存的方式就通过page fault机制来实现的。

当我们访问一个内存地址时,

1.如果该地址非法(访问系统为进程分配的地址空间之外的物理内存),或者我们对其没有访问权限;

2.

如果地址合法,权限也正确,那么还得分两种情况来讨论。第一种情况是PTE不存在,这会出现在:

  • 对于anonymous page,用户空间使用malloc()进行内存申请时(对应底层的实现是mmap或者brk),内核并不会立刻为其分配物理内存,而只是为请求的进程的rbtree管理的vma信息中记录(添加或更改)诸如内存范围和标志之类的信息。

只有当内存被真正使用,触发page fault,才会真正分配物理页面和对应的页表项,即demand alloction,对应的函数实现是do_anonymous_page()。通过mmap映射建立的heap和stack等内存区域,在初始未使用时,也适用于这样的规则。

技术图片

  • 对于page cache, 在发生内存回收后,部分text(code)段的页面会被discard,部分data段的页面会被writeback,之后再次访问这些页面,也将出现page fault。此时,需要从外部存储介质中,将页面内容调回内存,即demand paging,对应的函数实现是do_fault()。
技术图片
图片来源于http://jake.dothome.co.kr/wp-content/uploads/2017/01/do_fault-1.png

第二种情况是PTE存在,但其中的"P(resent)"位为0,说明这是一个之前被swap out出去的anonymous page。现在PTE里存储的不是物理页面的编号PPN,而是外部swap area中slot的编号swp_entry_t,需要通过do_swap_page(),执行swap in操作将页面的内容拷贝回内存。

/* orig_pte是指发生page fault时的PTE */
if (!pte_present(vmf->orig_pte))
    return do_swap_page(vmf);

技术图片

发生page fault时,如果目标页面驻留在外部存储器,那么需要开销较大的I/O操作,这种page fault被称为"major"的。而如果目标页面就在内存中(比如swap cache),只是缺少一个对该页面的引用而已,这种page fault不需要重新分配内存页面,代价较小,因此被称为"minor"的。

 

Linux进程如何访问内存

        Linux下,进程并不是直接访问物理内存,而是通过内存管理单元(MMU)来访问内存资源,原因后面会讲到。

为什么需要虚拟内存地址空间

       假设某个进程需要4MB的空间,内存假设是1MB的,如果进程直接使用物理地址,这个进程会因为内存不足跑不起来。既然进程不是直接访问物理内存,那么进程中涉及的内存地址当然也不是物理内存地址。而是虚拟的内存地址,虚拟的内存地址和物理的内存地址之间保持一种映射关系,这种关系由MMU进行管理。每个进程都有自己独立的虚拟地址空间。

 

参考:https://zhuanlan.zhihu.com/p/66046257

https://cloud.tencent.com/developer/article/1459526

page fault

标签:and   来源   swap   developer   内存   dem   width   height   内存区域   

原文地址:https://www.cnblogs.com/0patrick/p/14139463.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!