当前位置: 首页 > news >正文

操作系统(9)虚拟内存-内存映射

在 Linux 中,内存映射 是一种将文件或设备的内容直接映射到进程虚拟地址空间的机制,使进程能像操作普通内存一样访问文件或共享内存,核心由系统调用 mmap 实现,涉及虚拟内存管理、缺页异常处理等底层机制。以下是其关键知识点的详细解析:

9.1内存映射的分类与概念

  1. 文件映射将磁盘文件的一段区间映射到进程虚拟地址空间,数据源为文件。例如数据库、大文件的随机读写场景,可避免频繁的 read/write 系统调用,提升性能。

  2. 匿名映射无文件支持的内存映射,将物理内存直接映射到虚拟地址空间(如进程堆、栈或共享内存)。典型场景包括进程内大块内存分配、父子进程共享内存等。

  3. 共享映射与私有映射

    • 共享映射:多个进程映射同一区域时,修改会同步到文件或其他进程。
    • 私有映射:修改仅在当前进程的内存副本中生效,不影响文件或其他进程。

9.2核心系统调用:mmap 与 munmap

1. mmap 原型与参数
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
  • addr:期望的映射起始地址(通常设为 NULL,由系统自动分配)。
  • length:映射区域的大小(需页对齐,通常为 4KB 的整数倍)。
  • prot:内存保护权限(PROT_READPROT_WRITEPROT_EXECPROT_NONE 组合)。
  • flags:映射类型(如 MAP_SHAREDMAP_PRIVATEMAP_ANONYMOUS)。
  • fd:文件描述符(匿名映射时为 -1)。
  • offset:文件内的偏移量(需页对齐)。
2. munmap 用于解除映射·        
int munmap(void *addr, size_t length);

9.3底层实现机制

  1. 虚拟内存区域(vm_area_struct映射时,内核在进程虚拟地址空间中创建一个 vm_area_struct 结构体,描述该映射区域的起始 / 结束地址、权限、映射类型等信息。

  2. 延迟分配与缺页异常内核采用 “延迟分配” 策略:仅在进程首次访问映射区域时,触发缺页异常,再分配物理内存并建立页表映射:

    • 文件映射:从文件读取数据到物理页,更新页表。
    • 匿名映射:直接分配物理页,初始化后更新页表。
  3. 页表与地址翻译通过多级页表(如 PGD→PUD→PMD→PTE)管理虚拟地址到物理地址的映射。MMU(内存管理单元)在访问时自动解析页表,若页表项不存在则触发缺页异常,由内核处理。

9.4典型应用场景

  1. 高效文件操作示例:将文件映射到内存后直接修改,无需 read/write

    #include <fcntl.h>
    #include <sys/mman.h>
    int fd = open("test.txt", O_RDWR);
    char *map = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    strcpy(map, "直接修改文件内容");
    munmap(map, 4096);
    close(fd);
    
  2. 进程间共享内存两个进程映射同一文件的共享区域,实现数据共享:

    // 进程A
    int fd = open("shared.dat", O_CREAT | O_RDWR, 0666);
    ftruncate(fd, 4096);
    char *shm = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    strcpy(shm, "共享数据");// 进程B
    int fd = open("shared.dat", O_RDWR);
    char *shm = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    printf("%s\n", shm); // 输出“共享数据”
    
  3. 匿名内存分配分配不关联文件的内存区域(类似 malloc,但由内核直接管理):

    void *ptr = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    strcpy((char*)ptr, "匿名映射内存");
    munmap(ptr, 4096);
    

http://www.dtcms.com/a/544435.html

相关文章:

  • 30. 文件IO (1)
  • 技术深析:衡石 Agentic BI 的架构革命与核心技术突破
  • UVa 12333 Revenge of Fibonacci
  • rank(A+E) >= rank(A)证明
  • 未来之窗昭和仙君(四十三)开发布草管理系统修仙版——东方仙盟筑基期
  • VMware 虚拟机网络故障
  • 河南省建设厅举报网站建网站需要多少资金
  • 网站开发常用的谷歌插件企业首次建设网站的策划流程
  • 计算机3D视觉:Pytorch3d的环境配置与初步使用
  • 国产化转型实战:制造业供应链物流系统从MongoDB至金仓数据库迁移全指南
  • 从零开始学 Rust:环境搭建、基础语法到实战项目全流程
  • S11e Protocol 完整白皮书
  • CUDA:通往大规模并行计算的桥梁
  • AR智能眼镜:变电站巡检误操作的“电子安全员”
  • Rust 中的内存对齐与缓存友好设计:性能优化的隐秘战场
  • Springboot3+mqttV5集成(Emqx 5.8.3版本)
  • 东莞网站建设设技术支持网站
  • 高州网站建设公司欧洲vodafonewifi18mmpcc
  • 第二章、Docker+Ollama封神!2步装Qwen+Deepseek小型模型
  • Rust——Trait 定义与实现:从抽象到实践的深度解析
  • Spring AI加DeepSeek实现一个Prompt聊天机器人
  • 怎么判断我的电脑是否支持PCIe 5.0 SSD?Kingston FURY Renegade G5
  • Kotlin Map扩展函数使用指南
  • 批量地址解析坐标,支持WPS、EXCEL软件,支持导出SHP、GEOJSON、DXF等文件格式
  • 【Docker】【2.docker 安装 ubuntu 桌面版】
  • 单片机上的动态数码管
  • 怎么创建网站相册甘肃网站建设项目
  • 前端三剑客之一 CSS~
  • 仓颉语言运算符使用方法详解
  • 视频编码原理