【计算机架构】操作系统中的内存管理:换页与缺页异常

本文探讨了操作系统如何通过换页机制回收物理内存,当程序访问未映射的虚拟页时的缺页异常处理过程。还介绍了按需页分配策略,以及预取机制优化磁盘操作。核心内容涉及内存扩展、异常处理和资源调度。

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

换页机制思想: 该机制的基本思想是当物理内存容量不够的时候,操作系统应该把若干物理页的内容写到类似于磁盘这种容量更大更加便宜的存储设备中,然后就可以回收这些物理页供其他程序使用了。

举个例子,有一个程序A,其中A的一个物理页为P(对应于程序A虚拟内存中的虚拟页V)时,当操作系统希望从程序A那里回收P时,操作系统就需要将物理页P中的内容写到磁盘的一个位置,并且在程序A的页表中,去除虚拟页V的映射,同时记录该物理页被换到磁盘上的对应位置。该过程叫做物理页P的换出。然后,物理页P就可以被操作系统回收,并且分配给别的应用程序使用,虚拟页V就处于已分配但未映射到物理内存的状态。

缺页异常: 它是和换页机制密不可分的,也是换页机制能够工作的前提,当应用程序访问已分配但未映射至物理内存的虚拟页时,就会发生缺页异常。此时操作系统会运行操作系统预先设置好的缺页异常处理函数,该函数会找到一个空闲的物理页,将之前写到磁盘上的数据内容重新加载到该物理页中,并且在该程序的页表中填写虚拟地址到这一物理页的映射,该过程被称为换入

利用换页机制,操作系统就可以把物理内存中的放不下的数据临时放到磁盘上,等到需要的时候再放回到物理内存中,从而能够为应用程序提供超过物理内存容量的内存空间。

由于换页过程涉及耗时的磁盘操作,因此操作系统往往会引入预取机制进行优化。它的原理为:当发生换入操作时,预测还有哪些页即将被访问,提前将他们一并换入物理页内存,从而减少发生缺页异常的次数。

按需页分配: 当应用程序申请分配内存时,操作系统可选择将新分配的虚拟页标为已分配但未映射至物理内存状态,而不必为这个虚拟页分配对应的物理页。然后当应用程序访问这个虚拟页时,就会触发缺页异常,此时操作系统才真正为这个虚拟页分配对应的物理内存,并且在页表中填入对应的映射。这种按需分配的机制,使得操作系统能在应用程序真正需要使用物理内存的时候再分配物理页,这使得操作系统能够有效地节约物理内存,提高资源的利用率。

### malloc 是否分配物理内存还是匿名内存 #### ### 1. malloc 的工作原理 `malloc` 是一种用于动态内存分配的标准库函数,其主要职责是从堆中获取指定大小的连续存储空间并返回指向这块空间起始位置的指针。然而,`malloc` 并不直接处理物理内存,而是通过操作系统提供的接口间接完成这一过程[^1]。 #### ### 2. 物理内存 vs 匿名内存 - **物理内存**:指的是计算机硬件上的实际 RAM 资源。 - **匿名内存**:如前所述,是指未任何文件关联的虚拟内存区域,通常由操作系统负责将其映射至物理页面或交换设备上[^3]。 #### ### 3. malloc 如何分配内存 在大多数现代 Unix-like 系统中,`malloc` 实现依赖两种不同的方法来扩展进程的可用地址范围: - 当所需内存较小时,`malloc` 可能会调用 `brk()` 或者 `sbrk()` 来调整数据段边界从而获得新的虚拟地址区间[^2]; - 若请求较大块的连续空间,则更倾向于采用 `mmap()` 映射一段全新的匿名内存区域[^4]。 无论是哪种情况下的初始阶段,所获知的结果均属于虚拟地址范畴内的资源,并非立即对应的实体硬件单元。只有当这些虚拟地址首次尝试访问时(例如写入操作),才会触发缺页中断事件进而促使操作系统决定是否以及如何将它们绑定到真实的物理帧之上[^1]。 因此可以说,默认状态下 `malloc` 所分配出来的实际上是匿名内存而非直接就是物理内存本身。至于何时何处发生从虚拟层面向底层转换的动作则取决于当前系统的负载状况以及其他相关政策因素的影响。 另外值得注意的一个细节在于,对于经由 `brk/sbrk` 增加的部分来说,在释放之后一般会被放入本地维护的小型缓冲区内等待重用而不轻易交回给全局管理者;而对于那些依靠 `mmap` 构建起来的大尺寸对象而言,则会在适当条件下彻底消除掉相应条目并将控制权重新交付给内核层次进行统一调度安排。 --- ```c #include <stdio.h> #include <stdlib.h> int main(){ void* ptr = malloc(1); // 请求单字节大小的空间 if(ptr != NULL){ printf("Memory successfully allocated.\n"); free(ptr); // 解除占用状态 }else{ fprintf(stderr,"Failed to allocate memory\n"); } return 0; } ``` 此代码片段展示了典型场景下运用 `malloc` 和配套服务命令 `free` 完成基本任务的过程示意。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

别出BUG求求了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值