Linux缺页异常

2022/7/28 5:22:45

本文主要是介绍Linux缺页异常,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

关键词说明:
VA:Virtual Address 虚拟地址
PA:Physical Address 物理地址
MMU:Memory Manage Unit 内存管理单元
TLB:Translation Lookaside Buffer 旁路快表缓存/地址变换高速缓存
PTE:Page Table Entry 分页表项

(1)    内存延时分配

    以Linux系统为例,每个进程拥有独立的虚拟地址空间,32位系统是4GB的VA虚拟地址空间,64位则可以分配更大。但是在实际中没有必要也不可能为每个进程都分配4G以上的PA物理地址空间。即VA很大,但是实际对应的PA很小。

    在Linux中,分页模式在逻辑上将虚拟内存和物理内存同时等分成固定大小的块。这些块在虚拟内存上称之为「页」,而在物理内存上称之为「页帧」,并交由 CPU 中的 MMU 模块来负责页帧和页之间的映射管理。

    所以只有当程序运行时用到了才会去VA中寻找对应的页帧,找不到就再进行分配,这就是内存的延时分配机制。保证内存利用率和服务器利用率,资源合理分配。

(2)    MMU和PTE

    CPU不和物理内存交互,而是通过MMU进行内存管理。每个进程都有自己的页表,存储进程中VA到PA的映射关系,像一张地图。MMU收到CPU的VA后查询页表,来确定是否存在映射以及读写权限是否正常。

    而对于4GB的虚拟地址且大小为4KB的页,一级页表将有2^20个表项,页表占有连续内存并且存储空间大,多级页表可以有效降低页表的存储空间以及内存连续性要求,但是多级页表同时也带来了查询效率问题。

    总结:进程拥有自己的页表,CPU运行该进程,MMU会去页表查询VA和PA的映射关系。而不同页组成页表,可以选择一级连续存储,但占用空间大。也可以选择多级页表离散存储,但查询效率低。

(3)    MMU和TLB

    CPU根据用户进程提供的虚拟地址来获取真实数据,交给MMU。但是MMU在PTE页表中查询费时费力,所以集成一个TLB快表来加速寻址,即CPU向MMU传入虚拟地址时,MMU先查询TLB快表,有没有直接对应的物理地址,有就直接把PA发送给CPU,没有就去PTE页表查询,并更新TLB。

    所以TLB不满的时候直接存储新纪录,但TLB内存较小,当满了就把旧纪录清除写入新纪录。

    总结:MMU收到CPU的VA先查询TLB,没有找到PA再查询PTE,相当于TLB快表存储的是CPU常用的VA映射PA。可以认为TLB时MMU的缓存。

(4)    缺页异常

    如果CPU给MMU的VA在TLB和PTE都没找到对应的物理页帧或者权限不对,这就是一个缺页异常,Page Fault,它是一个由硬件中断触发的可以由软件逻辑纠正的错误。

    PageFault:目标进程内存页在物理内存没有对应的页帧或无相应权限,CPU就没有数据,无法工作,用户进程被迫停止,出现了缺页中断,进程从用户态—>内核态。将缺页中断交给内核中的Page Fault Handler 处理。

(5)    缺页异常的分类处理

    在内核的Page Fault Handler中会根据缺页中断的不同类型进行不同处理。

    Hard Page Fault

    也被称为Major Page Fault,翻译为硬缺页错误/主要缺页错误,这时物理内存中没有对应的页帧,需要CPU打开磁盘设备读取到物理内存中,再让MMU建立VA和PA的映射。

    Soft Page Fault

    也被称为Minor Page Fault,翻译为软缺页错误/次要缺页错误,这时物理内存中是存在对应页帧的,只不过可能是其他进程调入的,发出缺页异常的进程不知道而已,此时MMU只需要建立映射即可,无需从磁盘读取写入内存,一般出现在多进程共享内存区域。

    Invalid Page Fault

    翻译为无效缺页错误,比如进程访问的内存地址越界访问,又比如对空指针解引用内核就会报segment fault错误中断进程直接挂掉。

 

(6)    缺页异常出现的原因

A. 非法操作访问越界

这种情况产生的影响也是最大的,也是Coredump的重要来源,比如空指针解引用或者权限问题等都会出现缺页错误。

(Coredump:程序由于异常或BUG在运行中退出或终止,产生一个叫core的文件,该文件包含了程序运行时的内存,寄存器状态,堆栈指针,内存管理信息以及各种函数调用堆栈信息。即程序工作当前状态存储生成的第一个文件,通过工具分析这个文件,可以定位到程序异常退出时调用的堆栈信息,找出问题所在并及时解决。Core文件默认存储位置与对应的exe文件在同一目录下,文件名时core。查看core文件所在位置: cat  /proc/sys/kernel/core_pattern)

B. 使用malloc新申请内存

malloc机制是延时分配内存,当使用malloc申请内存时并未真实分配物理内存,等到真正开始使用malloc申请的物理内存时发现没有才会启动申请,期间就会出现Page Fault。

C. 访问数据被swap换出

物理内存是有限资源,当运行很多进程时并不是每个进程都活跃,对此OS会启动内存页面置换将长时间未使用的物理内存页帧放到swap分区来腾空资源给其他进程,当存在于swap分区的页面被访问时就会触发Page Fault从而再置换回物理内存。

总结:触发Page Fault的原因可能有很多,归根到底也只有几种大类:

(1)如使用共享内存区域,没有存储VA->PA的映射但是存在物理页帧的软缺页错误,在Page Table/TLB中建立映射关系即可。

(2)访问的地址在物理内存中确实不存在,需要从磁盘/swap分区读入才能使用,这种性能影响会比较大,因为磁盘太慢了,尽量使用高性能的SSD来降低延时。

(3)访问的地址内存非法,缺页错误会升级触发SIGSEGV信号结束进程,这种属于可以导致进程挂掉的一种缺页错误

 

 

参考文章:

https://blog.csdn.net/Mind_programmonkey/article/details/116722530【计算机操作系统-内存管理】-内存的缺页异常是什么?现在有逻辑地址,但是物理地址没有加载到内存会怎么样?

https://liam.page/2017/09/01/page-fault/【内存缺页错误】

https://blog.51cto.com/u_15471709/4868198【coredump详解】



这篇关于Linux缺页异常的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程