内存映射工作原理和适用场景
Linux 内存映射(Memory Mapping)是一种将文件或其他资源直接映射到进程虚拟内存地址空间的机制,允许进程像访问内存一样访问文件或设备。这种机制通过 mmap() 系统调用实现,常用于高效文件操作、进程间共享内存等场景。
1. 内存映射的核心概念
-
虚拟内存区域:每个进程的虚拟地址空间中存在一个“内存映射区域”,用于存放映射的文件或匿名内存。(用户空间分为代码段、数据段、堆、栈,还有内存映射区域。)
-
页缓存(Page Cache):文件被映射到内存时,实际数据存储在页缓存中,内核自动管理缓存的加载和回写。
-
共享与私有映射:
- 共享映射(MAP_SHARED):修改会同步到文件,其他进程可见。
- 私有映射(MAP_PRIVATE):修改仅对当前进程有效,不会写回文件。
-
具体流程:

- mmap:进程通过调用 mmap 系统调用来请求将文件或设备映射到进程的虚拟地址空间。
- 更新页表:操作系统更新进程的页表,以便将虚拟地址映射到正确的物理内存地址。
- 虚拟地址(vm_addr):CPU生成的虚拟地址,用于访问进程的虚拟内存空间。
- MMU查询:当CPU需要访问虚拟地址时,它会向内存管理单元(MMU)查询该虚拟地址对应的物理地址。
- 查进程用户空间页表:MMU会查询进程的用户空间页表,以找到与虚拟地址对应的物理地址。
- 物理地址:MMU返回虚拟地址对应的物理地址。
- 直接操作物理内存的数据:一旦获得了物理地址,CPU就可以直接访问物理内存中的数据。
2. mmap() 系统调用
#include <sys/mman.h>void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
int munmap(void *addr, size_t length);
参数说明:
- addr:建议映射的起始地址(通常设为
NULL,由内核选择)。 - length:映射区域的长度。
- prot:保护权限(
PROT_READ、PROT_WRITE、PROT_EXEC、PROT_NONE)。 - flags:映射类型(
MAP_SHARED、MAP_PRIVATE、MAP_ANONYMOUS等)。 - fd:文件描述符(匿名映射时设为
-1)。 - offset:文件偏移量(通常为 0)。
返回值:
- 成功:返回映射区域的起始地址。
- 失败:返回
MAP_FAILED((void *) -1)。
3. 内存映射的类型
(1)文件映射
将文件内容映射到内存,适用于高效读写文件:
int fd = open("file.txt", O_RDWR);
void *addr = mmap(NULL, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
(2)匿名映射
不关联文件,用于动态分配内存或进程间共享:
void *addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
4. 内存映射的优势
- 减少数据拷贝:文件直接通过页缓存访问,无需
read()/write()的系统调用开销。 - 高效处理大文件:仅加载实际访问的部分到内存,避免一次性读取整个文件。
- 共享内存:多个进程映射同一文件/匿名区域,可实现高效进程间通信(IPC)。
- 延迟加载:数据按需加载到内存(缺页中断机制)。
5. 典型应用场景
- 文件读写优化:数据库(如 LevelDB)、图像处理库(如 OpenCV)常用
mmap加速 I/O。 - 动态库加载:加载共享库(
.so文件)时,系统通过内存映射将代码段映射到进程空间。 - 进程间通信(IPC):共享内存(搭配
MAP_SHARED)。 - 内存分配:
glibc的malloc()对大块内存使用mmap分配。
6. 注意事项
- 对齐要求:
offset必须是页大小的整数倍(通常 4KB)。 - 权限匹配:
prot和flags必须与文件打开模式兼容(如只读文件不能映射为PROT_WRITE)。 - 同步数据:修改后需调用
msync()确保数据写回磁盘。 - 资源释放:
munmap()不会自动关闭文件描述符。 - 信号处理:访问超出文件大小的映射区域可能触发
SIGBUS信号。
7. 示例代码
通过 mmap 修改文件内容
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main() {int fd = open("test.txt", O_RDWR);struct stat st;fstat(fd, &st);off_t size = st.st_size;// 映射文件到内存char *addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);if (addr == MAP_FAILED) {perror("mmap failed");return -1;}// 修改文件内容addr[0] = 'H';addr[1] = 'i';munmap(addr, size); // 解除映射close(fd);return 0;
}
8. 相关工具
- /proc/[pid]/maps:查看进程的内存映射区域。
- pmap:命令行工具,显示进程内存映射信息。
总结
Linux 内存映射通过 mmap 提供了一种高效、灵活的内存管理机制,广泛应用于文件操作、进程间通信和内存分配。理解其工作原理和适用场景,能帮助开发者优化程序性能并简化复杂任务(如共享内存)。
相关文章:
内存映射工作原理和适用场景
Linux 内存映射(Memory Mapping)是一种将文件或其他资源直接映射到进程虚拟内存地址空间的机制,允许进程像访问内存一样访问文件或设备。这种机制通过 mmap() 系统调用实现,常用于高效文件操作、进程间共享内存等场景。 1. 内存映…...
【Nginx + Keepalived 实现高可用的负载均衡架构】
使用 Nginx Keepalived 可以实现高可用的负载均衡架构,确保在某个 Nginx 节点故障时,自动将流量转移到备用节点。以下是详细的实现步骤: 1. 架构概述 Nginx:作为负载均衡器,将流量分发到后端服务器。Keepalived&…...
自动驾驶超声波雷达:市场潜力爆发,引领未来出行新趋势
在自动驾驶技术的飞速发展中,自动驾驶超声波雷达作为一项关键技术,正逐渐崭露头角,其重要性及市场增长潜力不容忽视。本文将深入探讨自动驾驶超声波雷达的重要性、市场增长趋势、显著优势、全球市场规模与驱动因素、主要市场参与者以及不同地…...
Apache服务器的基础配置(认证考试笔记)
Apache服务器的基本配置 配置Apache服务器,有如下需求: 不能修改Apache默认配置文件建立虚拟主机www.test.com,端口80将URLwww.test.com/data的请求引至目录/web/database,将URL www.test.com/img的请求导至目录/web/imagesweb/…...
41.兼职网站管理系统(基于springbootvue的Java项目)
目录 1.系统的受众说明 2.相关技术 2.1 B/S架构 2.2 Java技术介绍 2.3 mysql数据库介绍 2.4 Spring Boot框架 3.系统分析 3.1 需求分析 3.2 系统可行性分析 3.2.1技术可行性:技术背景 3.2.2经济可行性 3.2.3操作可行性: 3.3 项目设计目…...
Linux ARM64 将内核虚拟地址转化为物理地址
文章目录 前言一、通用方案1.1 kern_addr_valid1.2 __pa 二、ARM64架构2.1 AT S1E1R2.2 is_kernel_addr_vaild2.3 va2pa_helper 三、demo演示参考资料 前言 本文介绍一种通用的将内核虚拟地址转化为物理地址的方案以及一种适用于ARM64 将内核虚拟地址转化为物理地址的方案&…...
spring学习(使用spring加载properties文件信息)(spring自定义标签引入)
目录 一、博客引言。 二、基本配置准备。 (1)初步分析。 (2)初始spring配置文件。 三、spring自定义标签的引入。 (1)基本了解。 (2)引入新的命名空间:xmlns:context。 &…...
Flutter项目试水
1基本介绍 本文章在构建您的第一个 Flutter 应用指导下进行实践 可作为项目实践的辅助参考资料 Flutter 是 Google 的界面工具包,用于通过单一代码库针对移动设备、Web 和桌面设备构建应用。在此 Codelab 中,您将构建以下 Flutter 应用。 该应用可以…...
Linux(Ubuntu)安装pyenv和pyenv-virtualenv
Ubuntu安装pyenv和pyenv-virtualenv 安装 pyenv1. 下载 pyenv2. 配置环境变量3. 重启 Shell4. 安装依赖5.检测是否安装成功 安装 pyenv-virtualenv1. 安装 pyenv-virtualenv2. 配置环境变量3. 重启 Shell pyenv 的使用1. 查看可安装的 Python 版本2. 安装指定版本的 Python3. 查…...
调用DeepSeek官方的API接口
效果 前端样式体验链接:https://livequeen.top/deepseekshow 准备工作 1、注册deepseek官网账号 地址:DeepSeek 点击进入右上角【API开放平台】,并进行账号注册。 2、注册完成后,依次点击【API keys】-【生成API key】&#x…...
MFC线程安全案例
作者:小蜗牛向前冲 名言:我可以接受失败,但我不能接受放弃 如果觉的博主的文章还不错的话,还请点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、项目解析 二…...
【Elasticsearch】bucket_sort
Elasticsearch 的bucket_sort聚合是一种管道聚合,用于对父多桶聚合(如terms、date_histogram、histogram等)的桶进行排序。以下是关于bucket_sort的详细说明: 1.基本功能 bucket_sort聚合可以对父聚合返回的桶进行排序ÿ…...
计算机毕业设计——Springboot点餐平台网站
📘 博主小档案: 花花,一名来自世界500强的资深程序猿,毕业于国内知名985高校。 🔧 技术专长: 花花在深度学习任务中展现出卓越的能力,包括但不限于java、python等技术。近年来,花花更…...
MATLAB中count函数用法
目录 语法 说明 示例 对出现次数计数 使用模式对数字和字母进行计数 多个子字符串的所有出现次数 忽略大小写 对字符向量中的子字符串进行计数 count函数的功能是计算字符串中模式的出现次数。 语法 A count(str,pat) A count(str,pat,IgnoreCase,true) 说明 A c…...
Win11下搭建Kafka环境
目录 一、环境准备 二、安装JDK 1、下载JDK 2、配置环境变量 3、验证 三、安装zookeeper 1、下载Zookeeper安装包 2、配置环境变量 3、修改配置文件zoo.cfg 4、启动Zookeeper服务 4.1 启动Zookeeper客户端验证 4.2 启动客户端 四、安装Kafka 1、下载Kafka安装包…...
51c自动驾驶~合集49
我自己的原文哦~ https://blog.51cto.com/whaosoft/13164876 #Ultra-AV 轨迹预测新基准!清华开源:统一自动驾驶纵向轨迹数据集 自动驾驶车辆在交通运输领域展现出巨大潜力,而理解其纵向驾驶行为是实现安全高效自动驾驶的关键。现有的开…...
nexus部署及配置https访问
1. 使用docker-compose部署nexus docker-compose-nexus.yml version: "3" services:nexus:container_name: my-nexusimage: sonatype/nexus3:3.67.1hostname: my-nexusnetwork_mode: hostports:- 8081:8081deploy:resources:limits:cpus: 4memory: 8192Mreservations…...
ffmpeg -hwaccels
1. ffmpeg -hwaccels -loglevel quiet 显示ffmpeg支持的硬件设备 2. 输出 Hardware acceleration methods: vdpau cuda vaapi qsv drm opencl 3. 说明 输出中的cuda表示ffmpeg支持Nvidia 硬件设备。编译ffmpeg增加相关硬件设备的配置,输出会显示相应的信…...
Python——批量图片转PDF(GUI版本)
目录 专栏导读1、背景介绍2、库的安装3、核心代码4、完整代码总结专栏导读 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手 🏳️🌈 博客主页:请点击——> 一晌小贪欢的博客主页求关注 👍 该系列文章专栏:请点击——>Python办公自动化专…...
LabVIEW无人机飞行状态监测系统
近年来,无人机在农业植保、电力巡检、应急救灾等多个领域得到了广泛应用。然而,传统的目视操控方式仍然存在以下三大问题: 飞行姿态的感知主要依赖操作者的经验; 飞行中突发的姿态异常难以及时发现; 飞行数据缺乏系统…...
算法16(力扣451)——根据字符出现频率排序
1、问题 给定一个字符串 s ,根据字符出现的 频率 对其进行 降序排序 。一个字符出现的频率 是它出现在字符串中的次数, 返回 已排序的字符串。如果有多个答案,返回其中任何一个。 2、示例 (1) 输入: s "tree&q…...
Response 和 Request 介绍
怀旧网个人博客网站地址:怀旧网,博客详情:Response 和 Request 介绍 1、HttpServletResponse 1、简单分类 2、文件下载 通过Response下载文件数据 放一个文件到resources目录 编写下载文件Servlet文件 public class FileDownServlet exten…...
ADB详细教程
目录 一、ADB简介 二、配置 配置环境变量 验证是否安装成功 三、简单使用 基本命令 设备连接管理 USB连接 WIFI连接(需要USB线) 开启手机USB调试模式 开启USB调试 四、其他 更换ADB默认启动端口 一、ADB简介 ADB(Android Debug…...
Jenkins+gitee 搭建自动化部署
Jenkinsgitee 搭建自动化部署 环境说明: 软件版本备注CentOS8.5.2111JDK1.8.0_211Maven3.8.8git2.27.0Jenkins2.319最好选稳定版本,不然安装插件有点麻烦 一、安装Jenkins程序 1、到官网下载相应的版本war或者直接使用yum安装 Jenkins官网下载 直接…...
今日AI和商界事件(2025-02-11)
今日AI大事件主要包括以下几个方面: 一、行业竞购与合作变动 马斯克组团竞购OpenAI 据《华尔街日报》报道,马斯克率投资者财团出价974亿美元竞购OpenAI,欲使其回归开源公益使命。xAI支持此次竞购,若成功,xAI或与OpenA…...
oracle dbms_sqltune 使用
创建测试表 CREATE TABLE test_table (id NUMBER PRIMARY KEY,event_date DATE,value NUMBER );插入测试数据 DECLAREi NUMBER; BEGINFOR i IN 1..1000000 LOOPINSERT INTO test_table (id, event_date, value)VALUES (i, SYSDATE - MOD(i, 365), DBMS_RANDOM.VALUE(1, 1000)…...
大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡
大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡 背景 前端开发接口请求,调试,联调,接入数据,前端必不可少工具,postman是一个非常好…...
AI大语言模型
一、AIGC和生成式AI的概念 1-1、AIGC Al Generated Content:AI生成内容 1-2、生成式AI:generative ai AIGC是生成式 AI 技术在内容创作领域的具体应用成果。 目前有许多知名的生成式 AI: 文本生成领域 OpenAI GPT 系列百度文心一言阿里通…...
数智百问 | 制造企业如何降低产线检测数据的存储和管理成本?
在《“十四五”智能制造发展规划》等政策的推动下,以及新能源汽车、消费电子等品牌商对产品质量和供应商智能化水平要求的提升,半导体、电子制造、动力电池等先进制造行业企业纷纷推进产线智能化升级,并投入大量机器视觉检测设备以实现自动化…...
Pdf手册阅读(1)--数字签名篇
原文阅读摘要 PDF支持的数字签名, 不仅仅是公私钥签名,还可以是指纹、手写、虹膜等生物识别签名。PDF签名的计算方式,可以基于字节范围进行计算,也可以基于Pdf 对象(pdf object)进行计算。 PDF文件可能包…...
