阿里三面,mmap 没答好!

news2025/1/11 4:26:18

1、mmap基础概念

mmap 是一种内存映射文件的方法,即将一个文件或者其他对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一映射关系。

实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必调用read,write等系统调用函数。相反,内核空间的这段区域的修改也直接反应用户空间,从而可以实现不同进程的文件共享。如下图所示:

由上图可以看出,进程的虚拟地址空间,由多个虚拟内存区域构成。虚拟内存区域是进程的虚拟地址空间中的一个同质区间,即具有同样特性的连续地址范围。上图中所示的text数据段、初始数据段、Bss数据段、堆、栈、内存映射,都是一个独立的虚拟内存区域。而为内存映射服务的地址空间处在堆栈之间的空余部分。

linux 内核使用的vm_area_struct 结构来表示一个独立的虚拟内存区域,由于每个不同质的虚拟内存区域功能和内部机制不同;因此同一个进程使用多个vm_area_struct 结构来分别表示不同类型的虚拟内存区域。各个vm_area_struct 结构使用链表或者树形结构链接,方便进程快速访问。如下图所示:

vm_area_struct 结构中包含区域起始和终止地址以及其他相关信息,同时也包含一个vm_ops 指针,其内部可引出所有针对这个区域可以使用的系统调用函数。这样,进程对某一虚拟内存区域的任何操作都需要的信息,都可以从vm_area_struct 中获得。mmap函数就是要创建一个新的vm_area_struct结构 ,并将其与文件的物理磁盘地址相连。具体步骤如下:

2、mmap 内存映射原理

mmap 内存映射实现过程,总的来说可以分为三个阶段:

(一)进程启动映射过程,并在虚拟地址空间中为映射创建虚拟映射区域

1、进程在用户空间调用函数mmap ,原型:void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);

2、在当前进程虚拟地址空间中,寻找一段空闲的满足要求的连续的虚拟地址

3、为此虚拟区分配一个vm_area_struct 结构,接着对这个结构各个区域进行初始化

4、将新建的虚拟区结构(vm_area_struct)插入进程的虚拟地址区域链表或树中

(二)调用内核空间的系统调用函数mmap (不同于用户空间函数),实现文件物理地址和进程虚拟地址的一一映射关系

5、为映射分配新的虚拟地址区域后,通过待映射的文件指针,在文件描述符表中找到对应的文件描述符,通过文件描述符,链接到内核“已打开文集”中该文件结构体,每个文件结构体维护者和这个已经打开文件相关各项信息。

6、通过该文件的文件结构体,链接到file_operations模块,调用内核函数mmap,其原型为:int mmap(struct file *filp, struct vm_area_struct *vma),不同于用户空间库函数。

7、内核mmap函数通过虚拟文件系统inode模块定位到文件磁盘物理地址。

8、通过remap_pfn_range函数建立页表,即实现了文件地址和虚拟地址区域的映射关系。此时,这片虚拟地址并没有任何数据关联到主存中。

(三)进程发起对这片映射空间的访问,引发缺页异常,实现文件内容到物理内存(主存)的拷贝。

前两个阶段仅在于创建虚拟区间并完成地址映射,但是并没有将任何文件数据拷贝至主存。真正的文件读取是当进程发起读或者写操作时。

9、进程的读写操作访问虚拟地址空间这一段映射地址后,通过查询页表,先这一段地址并不在物理页面。因为目前只建立了映射,真正的硬盘数据还没有拷贝到内存中,因此引发缺页异常。

10、缺页异常进行一系列判断,确定无法操作后,内核发起请求掉页过程。

11、调页过程先在交换缓存空间中寻找需要访问的内存页,,如果没有则调用nopage函数把所缺的页从磁盘装入到主存中。

12、之后进程即可对这片主存进行读或者写的操作了,如果写操作改变了内容,一定时间后系统自动回写脏页面到对应的磁盘地址,也即完成了写入到文件的过程。

注:修改过的脏页面并不会立即更新回文件,而是有一段时间延迟,可以调用msync() 来强制同步,这样所写的内容就能立即保存到文件里了。

3、mmap和常规文件操作的区别

首先我们来回顾一下常规文件操作,函数的调用过程:

1、进程发起读文件请求

2、内核通过查找进程文件符表。

3、inode在address_space上查找要请求的文件页是否已经缓存在页缓存中。如果存在,则直接返回这片文件页的内容。

总的来说,常规文件操作为了提高读写效率和保护磁盘,使用了页缓存机制,这样造成了读文件时需要先将文件页从磁盘拷贝到缓存中,由于页缓存处在内核空间,不能被用户进程直接寻址,所以还需要将页缓存中数据页再次拷贝到内存对用的用户空间中。这样通过两次拷贝过程,才能完成进程对文件内容的获取。写操作也一样,待写入的Buffer在内核空间不能直接访问,必须先拷贝到内核空间对应的主存,再回写磁盘中,也是需要两次数据拷贝。而使用mmap 操作文件中,创建新的虚拟内存区域、建立文件磁盘地址和内存区域映射这两步,没有任何文件拷贝操作。而之后访问数据时,发现内存中并无数据而发起的缺失页异常过程,可以通过建立好的映射关系,只使用一次数据拷贝,就从磁盘中将数据传入内存的用户空间中,供过程使用。

总而言之,常规的文件操作需要从磁盘到页缓存再到用户主存的两次数据拷贝,而mmap操作文件,只需要从磁盘到用户主存的一次数据拷贝过程。说白了,mmap的关键点是实现了用户空间和内核的数据直接交互省去了空间不同数据不通的繁琐过程。因此 mmap效率更高。

mmap优点总结

由上文讨论可知,mmap 优点共有以下几点:

对文件的读取操作跨过了页缓存,减少了数据的拷贝次数,用内存读写取代了I/O读写,提高了读取的效率。

实现了用户空间和内核空间的高校交互方式,两空间的各自修改操作可以直接反映在映射的区域内,从而被对方空间及时捕捉。

提供进程间共享内存及互相通信的方式。不管是父子进程还是无亲缘关系进程,都可以将自身空间用户映射到同一个文件或者匿名映射到同一片区域。从而通过各自映射区域的改动,打到进程间通信和进程间共享的目的。

同时,如果进程A和进程 B 都映射了区域C,当A第一次读取C时候,通过缺页从磁盘复制文件页到内存中,但当B再读C的相同页面时,虽然也会产生缺页异常,但是不会从磁盘中复制文件过来,而是直接使用已经保存再内存中的文件数据。

可用于实现高效的大规模数据传输。内存空间不足,是制约大数据操作的一个方面,解决方案往往是借助于硬盘空间的协助,补充内存的不足。但是进一步造成大量的文件I/O操作,极大影响效率。这个问题可以通过mmap映射很好的解决。换句话说,但凡需要磁盘空间代替内存的时候,mmap都可以发挥功效。

mmap使用细节

使用mmap需要注意一点,mmap映射区域大小必须是物理页大小(page_size)的整数倍,原因是:内存的最小粒度是页,而进程虚拟地址空间和内存的映射单位也是以页为单位,为了匹配内存操作,mmap从磁盘到虚拟地址空间的映射也必须是页。

内核可以跟踪被内存映射的底层对象,大小。就是说,如果文件的大小一直再扩张,只要再映射区域范围内的数据,进程都可以依法得到,这和映射建立时文件的大小无关。

映射建立后,即使文件关闭,映射依然存在。因为映射的是磁盘的地址,不是文件本身,和文件句柄无关,同时可用于进程间通信的有效地址空间,不完全受限于被映射文件的大小,因为是按页映射。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/94897.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

给你30s,如何跟面试官讲清楚跳表

查找 假设有如下这样一个有序链表: 想要查找 24、43、59,按照顺序遍历,分别需要比较的次数为 2、4、6 目前查找的时间复杂度是 O(N),如何提高查找效率? 很容易想到二分查找,将查找的时间复杂度降到 O(Lo…

MipNeRF:多尺度、抗混叠NeRF

Mip-NeRF: A Multiscale Representation for Anti-Aliasing Neural Radiance Fields ​ ICCV 2021 文章目录Mip-NeRF: A Multiscale Representation for Anti-Aliasing Neural Radiance Fields原始NeRF的问题重点componentsCone TracingIPE-integrated positional encodingPE与…

微服务框架 SpringCloud微服务架构 多级缓存 47 Lua 语法入门 47.2 变量和循环

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 多级缓存 文章目录微服务框架多级缓存47 Lua 语法入门47.2 变量和循环47.2.1 数据类型47.2.2 变量47.2.3 循环47 Lua 语法入门 47.2 变量和…

人脸识别Face Recognition综述

综述:https://arxiv.org/pdf/2009.13290.pdf 人脸识别整个系统一般由三个关键要素构成:人脸检测(face detection)、人脸预处理(face preprocess),人脸表征(face representation&…

EtherCAT设备协议详解一、EtherCAT概述

EtherCAT简介: • 用于控制自动化技术的以太网(EtherCAT) 是一种基于以太网的现场总线系统 – 由倍福自动化™于2003年发明 – Beckhoff 创建了 EtherCAT 技术集团(ETG)于2004年推广议定书 –…

DBCO 点击化学:DBCO-PEG-COOH,DBCO-PEG-acid,羧基聚乙二醇环辛炔

一、产品描述: 西安凯新生物科技有限公司供应的:​DBCO-PEG-COOH,末端羧酸在活化剂(如EDC或HATU)存在下可与伯胺基反应,形成稳定的酰胺键。DBCO 点击化学可以在水性缓冲液中运行,也可以在有机溶…

来啦|深度讲解风控模型中的参数调优

大数据时代的风控体系必有模型部分的参与,用策略贯穿整个风控体系,以数据为驱动,模型一定是标配内容。于是在模型的建设上,如何精细化地输出一套有效的模型,就是在精细化管理上非常重要的一个差异点。不管传统的逻辑回…

MATLAB处理语音信号基本函数、模块

目录 一、sound函数 二、symerr函数用来计算错误码元数目和误码率 三、From Workspace 模块 四、To Workspace模块 一、sound函数 sound函数可以用来播放音频数据,将矩阵变为立体声播放。 二、symerr函数用来计算错误码元数目和误码率 三、From Workspace 模…

【High 翻天】Higer-order Networks with Battiston Federico (2)

目录测量矩阵表示中心化测度度(degree)路径(path)特征向量中心三元闭包和聚类系数单纯同调高阶Lapalacian算子超图拉普拉斯组合拉普拉斯接上回说到了高阶的表示方法,接下来开始高阶系统的测量方法。 测量 具体来说就…

逻辑越权总结(超详细总结涉及各类越权)

逻辑越权总结(超详细总结涉及各类越权)1.逻辑越权1.1.漏洞原理1.2.漏洞原因1.3.水平越权1.3.1.原理1.3.2.漏洞出现位置1.3.3.危害1.3.4.案例1.3.4.1.登录账号1.3.4.2.获取信息1.3.4.3.修改信息1.4.垂直越权1.4.1.原理1.4.2.漏洞出现位置1.4.3.条件1.4.4.…

艾美捷CpG ODN——ODN 1585说明书

艾美捷CpG ODN系列——ODN 1585:CpG寡脱氧核苷酸(A型)优化用于NK细胞活化,具有混合的磷酸二酯酶/硫代磷酸酯主链。小鼠TLR9(Toll样受体9)的特异性配体。 艾美捷CpG ODN 丨ODN 1585化学性质: 序…

kruskalCase克鲁斯卡尔算法

介绍 它的特点和Prim算法不一样,Prim是以点为主,通过顶点遍历没有访问的节点计算最小权重直至一条最小边出来;而Kruskal算法是以边为主,时间复杂度要低一些0(edge); 什么是最小生成树 最小生成树:在一个有n个结点的…

blender教程

文章目录Three的部分课件blender相关资源模型下载地址视图基本操作实现甜甜圈下落的动画day01笔记Three的部分课件 blender相关资源 模型下载地址 视图基本操作 shiftd 复制多个 g键移动 x y z锁定方向 A可以全选 然后选择大小 s 键 拖拽大小 ctrl a 全部应用 切换到不同的编…

Python 图表利器 pyecharts

随着互联网的高速发展,数据量也在疯狂增长,近几年数据分析,数据挖掘的岗位越来越吃香。说到数据分析,就离不开数据的可视化,毕竟图表比冷冰冰的数字直观,一眼就可以看出趋势和结论,毕竟一图胜千…

【AIOT】BLE Paper Relative

Billah, Md Fazlay Rabbi Masum, et al. “BLE Can See: A Reinforcement Learning Approach for RF-based Indoor Occupancy Detection.” Proceedings of the 20th International Conference on Information Processing in Sensor Networks (co-located with CPS-IoT Week 20…

对象池模式

一、对象池模式 1、定义 对象池模式(Object Pool Pattern)是将对象预先创建并初始化后放入对象池中,对象提供者就能利用已有的对象来处理请求,减少频繁创建对象锁占用的内存空间和初始化时间。属于创建型设计模式。 一个对象池包…

python 模板注入

web 程序包括两个文件: flask-test.py 和 Config.py 文件 #!/usr/bin/env python # -*- coding:utf8 -*- import hashlib import logging from datetime import timedelta from flask import Flask from flask import request from flask import config from flask…

基于java(springboot)篮球竞赛预约管理系统(java毕业设计)

基于java(springboot)篮球竞赛预约管理系统 篮球竞赛管理系统是基于java编程语言,mysql数据库,springboot框架和idea工具开发,本系统分为用户和管理员两个角色,其中用户可以在线注册登陆,查看平台公告,查看…

JSP运动会信息网站

开发工具(eclipse/idea/vscode等): 数据库(sqlite/mysql/sqlserver等): 功能模块(请用文字描述,至少200字): 模块划分:通知类型、通知信息、裁判信息、运动员信息、项目类型、项目 信息、场地信息、项目安排、报名信息…

【记录】ubuntu20.04安装nvidia显卡驱动

新安装的Ubuntu20.04系统,如果想进行人工智能相关的学习,需要配置一系列的环境,这里我记录下具体的安装过程。 Nvidia显卡驱动的安装 1 安装前需要安装依赖(必须执行) sudo apt-get update #更新软件列表 #安装编译依赖 sudo apt-get inst…