page fault的两种区别(major、minor)

本文探讨了pagefault缺页异常的两种类型:majorpagefault和minorpagefault,详细解析了它们的区别,以及在Linux系统中如何触发这两种异常。此外,文章还解释了为什么即使数据已经存在于PageCache中,仍需要触发minorfault,这是因为虚拟地址和物理地址的映射关系尚未建立。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

page fault缺页异常分为两种类型,一种叫做major page fault,这种类型的缺页可以通过 Disk IO来满足,另一种叫做minor page fault,这种缺页可以直接利用内存中的缓存页满足。

区别

对于IO子系统来说,内核中的分层结构从上到下:

VFS--> EXT4/EXT3-->Page Cache--> General Block Layer --> IO Scheduler --> Disk Driver

那么如果访问一个地址时,与该地址空间vma绑定的数据还存在于Disk上,那么此时即会触发一次major fault;如果访问一个地址时,与之绑定的vma对应的地址空间已经被内核加载到了Page Cache中,那么此时只需要把该Page映射到vma中即可,这种异常即为一次minor fault。
对于内核不熟悉的人此时有一个疑问:为什么数据已经被加载内核中的Page Cache了,理论上说直接访问就行了,为什么还要触发一次minor fault呢?
这里给出答案,懂得人可以略过,主要是因为虚拟地址和物理地址的映射关系并没有建立,我们知道Linux进程访问一块内存实际上使用的是虚拟内存,必须把对应虚拟地址空间和物理页面进行了映射才能够正常访问,那么vma结构体实际仅仅表示一个虚拟地址空间,必须把内核中Page Cache中的物理地址与进程vma虚拟地址空间进行映射才能正常被进程访问到。那么这就是该问题的答案了。

如何查看

从IO的原理来看,Major需要对disk进行IO操作,必然性能会有所下降。而对于运维来说,可以利用ps查看每个进程执行的Major、Minor page fault的次数

ps -eo min_flt,maj_flt,cmd | more

https://scoutapm.com/blog/understanding-page-faults-and-memory-swap-in-outs-when-should-you-worry

### Page Fault 的概念 在操作系统中,Page Fault 是指当程序尝试访问内存中的某个页面而该页面当前未加载到物理内存(RAM)时发生的一种事件。这种情况下,CPU 将触发异常处理机制来响应此请求[^1]。 具体来说,页表会记录虚拟地址与物理地址之间的映射关系。如果一个进程试图访问的页面并未实际存在于 RAM 中,则会产生 Page Fault。随后,操作系统的中断服务程序会被调用来执行必要的操作以解决问题,比如从磁盘交换文件读取数据或将其他不常用的页面置换出去以便腾出空间装载所需的页面[^2]。 ### 解决 Page Faults 的方法 #### 1. **Demand Paging** Demand paging 是一种常见的策略,在其中只有当某一页被真正需要的时候才会将其载入内存。这种方式可以有效减少初始启动时间以及节省有限的内存资源。一旦检测到缺页错误,系统就会通过查找对应的磁盘位置并将所需的数据搬移到可用帧上来修复这个问题[^3]。 #### 2. **Optimal Replacement Algorithms** 使用合适的页面替换算法对于管理频繁发生的 page faults 至关重要。一些经典的算法包括 FIFO(First In First Out), LRU(Least Recently Used),还有 OPT(Optimal Algorithm)等。这些算法帮助决定哪些现有的页面应该被淘汰从而让位于新需求的页面[^4]。 ```python def optimal_page_replacement(pages, capacity): frame_set = set() queue_order = [] page_fault_count = 0 for page in pages: if len(frame_set) < capacity and page not in frame_set: frame_set.add(page) queue_order.append(page) page_fault_count += 1 elif page not in frame_set: future_usage_index = [(i, pages.index(i)) for i in queue_order] farthest_future_use = max(future_usage_index, key=lambda item:item[1]) removed_page = farthest_future_use[0] frame_set.remove(removed_page) queue_order.remove(removed_page) frame_set.add(page) queue_order.append(page) page_fault_count += 1 return page_fault_count ``` 上述代码展示了一个简单的最优页面替换模拟器实现例子[^5]。 ### 结论 综上所述,理解并妥善处理 Page Fault 对于提升应用程序性能至关重要。采用适当的技术手段如 demand paging 和合理设计页面替换逻辑能够显著降低因 page fault 带来的延迟影响。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值