3.1.1操作系统四大功能之内存管理

今天讲操作系统的内存管理。我们经常使用操作系统进行工作,但是否想过为什么要引入内存管理?内存管理解决了什么问题,以及内存管理是怎么实现的。分页管理与分段管理各自的优势与缺点,以及它们结合优势后形成的段页式存储。

1.为什么要引入内存管理

众所周知,内存是存放临时数据的硬件。程序执行前要先放到内存中才能被CPU处理。因为要缓和CPU与硬盘之间的速度矛盾,而程序一般存储在硬盘中。

因此操作系统必须对内存空间进行合理的划分和有效的动态分配,这就是内存管理的概念。

2.内存管理的5个主要功能

内存空间的分配与回收地址转换:逻辑地址与物理地址的转换内存空间的扩充:覆盖、交换、虚拟技术内存共享:可重入代码存储保护

3.基本分页存储管理

物理地址:将物理内存划分为固定大小的 “页框”(如 4KB / 页),每个页框是内存分配的最小单位。

逻辑地址:把程序的逻辑地址空间同样划分为等长的 “页”,页号从 0 开始编号。

动态映射:程序的页可以分散存储在不同的页框中,通过 “页表” 建立页号与页框号的映射关系。

举个例子:

 

假设物理内存是一本字典,页框就是字典的每一页;程序则是另一本 “虚拟字典”,页是它的每一页。页表就像一本 “翻译手册”,记录虚拟页对应的实际页码。

页表结构:

 

页号物理块号

 

地址转换步骤:

计算页号和页内偏移

逻辑地址 = 页号 × 页大小 + 页内偏移

例如:页大小 4KB(12 位),逻辑地址 0x1234 → 页号 0x1,偏移 0x234。

查页表通过页号找到对应的物理块号。

生成物理地址物理块号 × 页大小 + 偏移。

4.快表(TLB):加速地址转换

痛点:每次查页表需访问内存,导致两次访存(逻辑地址→页表→物理地址),效率降低 50%。

解决方案:

快表CPU 内置的高速缓存,存储近期访问的页表项。局部性原理程序访问具有时间和空间局部性,近期访问的页大概率再次被访问。

地址转换优化:

先查快表命中则直接获取物理地址(1 次访存)。

未命中查页表更新快表,后续访问加速。

5.多级页表:解决页表过大的 “内存杀手”

问题:32 位系统页表可能占用 4MB 内存(1024 个页表项 × 4 字节),浪费严重。

两级页表方案:

一级页表记录二级页表的起始地址。二级页表记录页号与物理块号的映射。

优势:仅加载当前需要的二级页表,节省 99% 内存。

示例:

32 位地址分为:一级页号(10 位)+ 二级页号(10 位)+ 偏移(12 位)。一级页表项仅需 1024 个,每个指向一个二级页表(1024 项)。

 

至于之后的分段、段页式、虚拟内存管理,下期再介绍。末尾附上使用c语言实现的简单分页存储

#include <stdio.h>#include <stdlib.h>

#define PAGE_SIZE 4096#define NUM_PAGES 10

// 页表项结构体typedef struct {    int frame_number;    int valid;} PageTableEntry;

// 页表PageTableEntry page_table[NUM_PAGES];

// 初始化页表void init_page_table() {    for (int i = 0; i < NUM_PAGES; i++) {        page_table[i].frame_number = -1;        page_table[i].valid = 0;    }}

// 分配页框void allocate_page(int page_number, int frame_number) {    if (page_number >= 0 && page_number < NUM_PAGES) {        page_table[page_number].frame_number = frame_number;        page_table[page_number].valid = 1;    }}

// 地址转换int translate_address(int logical_address) {    int page_number = logical_address / PAGE_SIZE;    int offset = logical_address % PAGE_SIZE;

    if (page_number >= 0 && page_number < NUM_PAGES && page_table[page_number].valid) {        int frame_number = page_table[page_number].frame_number;        return frame_number * PAGE_SIZE + offset;    } else {        printf("页面错误: 逻辑地址 %d 对应的页面无效\n", logical_address);        return -1;    }}

int main() {    // 初始化页表    init_page_table();

    // 分配页框    allocate_page(0, 2);    allocate_page(1, 5);    allocate_page(2, 7);

    // 逻辑地址示例    int logical_address = 4500;    int physical_address = translate_address(logical_address);

    if (physical_address != -1) {        printf("逻辑地址 %d 转换后的物理地址是 %d\n", logical_address, physical_address);    }

    return 0;}    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值