首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

linux mmap 原理

Linux中的mmap()系统调用是一种内存映射文件的方法,它允许程序将文件或其他对象映射到其地址空间。以下是关于mmap()原理的详细解释,包括基础概念、优势、类型、应用场景以及可能遇到的问题和解决方法。

基础概念

mmap()

  • mmap()是一个系统调用,用于将文件或设备映射到进程的地址空间。
  • 它提供了一种高效的方式来访问文件内容,避免了频繁的系统调用和数据拷贝。

虚拟内存

  • mmap()操作的结果是在进程的虚拟地址空间中创建一个新的映射区域。
  • 虚拟内存管理器负责将虚拟地址转换为物理内存地址。

页表

  • 操作系统使用页表来跟踪虚拟地址到物理地址的映射关系。
  • 当进程访问映射的内存时,如果对应的物理页面不在内存中,会发生页错误(page fault),操作系统会加载相应的页面。

优势

  1. 减少系统调用:通过内存映射,可以直接在内存中进行读写操作,减少了传统的read/write系统调用次数。
  2. 提高I/O性能:内存映射可以利用操作系统的缓存机制,提高文件的读取速度。
  3. 简化编程模型:开发者可以直接使用指针对文件进行操作,就像操作普通内存一样。
  4. 支持共享内存:多个进程可以映射同一个文件到各自的地址空间,实现数据的共享。

类型

  • 文件映射:最常见的用法,将文件内容映射到内存。
  • 匿名映射:不对应任何文件,用于进程间通信或临时存储。
  • 共享映射:多个进程共享同一块内存区域。
  • 私有映射:每个进程都有自己的独立副本,对内存的修改不会影响其他进程。

应用场景

  1. 大文件处理:对于需要处理大文件的场景,mmap可以有效减少内存占用和提高I/O效率。
  2. 进程间通信(IPC):通过共享内存的方式实现高效的进程间数据交换。
  3. 数据库系统:许多数据库管理系统使用mmap来加速数据的读写操作。
  4. 内存映射文件系统:如tmpfs,它将文件存储在内存中,提供快速的读写能力。

可能遇到的问题及解决方法

问题1:内存泄漏

  • 原因:映射的内存没有被正确释放。
  • 解决方法:确保在不再需要映射时调用munmap()来解除映射。

问题2:访问非法内存

  • 原因:访问了未映射或超出映射范围的内存地址。
  • 解决方法:检查指针的有效性,确保在映射范围内进行操作。

问题3:性能下降

  • 原因:频繁的页错误导致系统性能降低。
  • 解决方法:优化文件访问模式,尽量减少不必要的页面置换。

示例代码

以下是一个简单的mmap()使用示例:

代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
    int fd = open("example.txt", O_RDONLY);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    struct stat sb;
    if (fstat(fd, &sb) == -1) {
        perror("fstat");
        close(fd);
        return 1;
    }

    char *addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
    if (addr == MAP_FAILED) {
        perror("mmap");
        close(fd);
        return 1;
    }

    // 直接访问文件内容
    printf("%s\n", addr);

    if (munmap(addr, sb.st_size) == -1) {
        perror("munmap");
    }

    close(fd);
    return 0;
}

在这个示例中,我们打开一个文件并将其映射到内存,然后直接读取并打印文件内容,最后解除映射并关闭文件描述符。

通过这种方式,可以高效地处理文件数据,同时简化了编程逻辑。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Linux mmap原理

Linux mmap原理 前言 Linux段页式内存管理 mmap mmap内存映射原理 文字概述 mmap函数参数介绍 源码解析 1. 文件映射 2....,但是并没有深入理解mmap在操作系统内部是如何实现的,原理是什么。...本文想要和大家一起来聊聊mmap的原理,本文整体脉络如下: linux段页式内存管理回顾 mmap原理 ---- Linux段页式内存管理 这里的段页式内存管理主要基于linux 0.11进行讲解...---- mmap内存映射原理 文字概述 mmap内存映射的实现过程,总的来说可以分为三个阶段: (一)进程启动映射过程,并在虚拟地址空间中为映射创建虚拟映射区域 进程在用户空间调用库函数mmap,原型...下面我们通过一幅图来对 mmap 的原理进行阐述: 从上图可以看出,mmap 的原理就是将虚拟内存空间映射到文件的页缓存,我们可以知道:对文件进行读写时需要经过页缓存进行中转的。

3.7K21

linux内存映射mmap原理分析

原理 首先,“映射”这个词,就和数学课上说的“一一映射”是一个意思,就是建立一种一一对应关系,在这里主要是只 硬盘上文件 的位置与进程 逻辑地址空间 中一块大小相同的区域之间的一一对应,如图1中过程1所示...图1.内存映射原理 既然建立内存映射没有进行实际的数据拷贝,那么进程又怎么能最终直接通过内存操作访问到硬盘上的文件呢?那就要看内存映射之后的几个相关的过程了。...()也是系统调用,如前所述,mmap()中没有进行数据拷贝,真正的数据拷贝是在缺页中断处理时进行的,由于mmap()将文件直接映射到用户空间,所以中断处理函数根据这个映射关系,直接将文件从硬盘拷贝到用户空间...图2.read系统调用原理 下面这个程序,通过read和mmap两种方法分别对硬盘上一个名为“mmap_test”的文件进行操作,文件中存有10000个整数,程序两次使用不同的方法将它们读出,加1,再写回硬盘...通过对比可以看出,read消耗的时间将近是mmap的两到三倍。

4.4K41
  • Linux内存映射——mmap

    Linux提供了mmap()函数,用来映射物理内存。...在驱动程序中,应用程序以设备文件为对象,调用mmap()函数,内核进行内存映射的准备工作,生成vm_area_struct结构体,然后调用设备驱动程序中定义的mmap函数。...2.mmap系统调用 mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。...三 mmap进行内存映射的原理 mmap系统调用的最终目的是将,设备或文件映射到用户进程的虚拟地址空间,实现用户进程对文件的直接读写,这个任务可以分为以下三步: 1.在用户虚拟地址空间中寻找空闲的满足要求的一段连续的虚拟地址空间...struct file *,struct vm_area_struct *); linux有2个方法建立页表: (1) 使用remap_pfn_range一次建立所有页表.

    5.8K10

    【Linux 内核 内存管理】mmap 系统调用源码分析 ① ( mmap 与 mmap2 系统调用 | Linux 内核中的 mmap 系统调用源码 )

    文章目录 一、mmap 与 mmap2 系统调用 二、Linux 内核中的 mmap 系统调用源码 一、mmap 与 mmap2 系统调用 ---- mmap 创建 " 内存映射 " 的 系统调用 有...2 种实现 , mmap 和 mmap2 ; 2 者区别是 : mmap 偏移单位是 " 字节 " , mmap2 偏移单位是 " 页 " , 但是在 arm 64 体系架构中 , 没有实现 mmap2..., 只实现了 mmap 系统调用 ; 二、Linux 内核中的 mmap 系统调用源码 ---- arm64 架构体系中 , 使用 mmap 系统调用 创建 " 内存映射 " , 调用 mmap 系统调用函数...函数 , 继续向下执行 ; mmap 系统调用代码如下 : SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg) { struct...>> PAGE_SHIFT); } 参考路径 : linux-4.12\mm\mmap.c#1534

    10.6K40

    【Netty】mmap 和 sendFile 零拷贝原理

    文章目录 一、 零拷贝 简介 二、 传统 BIO 数据拷贝分析 ( 4拷贝 4切换 ) 三、 mmap 内存映射 ( 3拷贝 4切换 ) 四、 sendFile 函数 ( Linux 2.1 优化 )..., 使用零拷贝能极大的提升数据传输性能 ; 零拷贝类型 : mmap ( 内存映射 ) 和 sendFile; 数据角度分析 : 在零拷贝机制中 , 整个数据在内存中只有一份数据 , 非零拷贝机制中...-> 内核态 -> 用户态 [ 1 ] [1] [1] DMA 全称 ( Direct Memory Access ) , 直接内存拷贝 , 该拷贝通过内存完成 , 不涉及 CPU 参与 ; 三、 mmap...4切换 ) 将硬盘中的文件映射到 内核缓冲区 , 用户空间中的应用程序也可以访问该 内核缓冲区 中的数据 , 使用这种机制 , 原来的 4 4 4 次数据拷贝减少到了 3 3 3 次 , 1 . mmap...2.4 优化 ) ( 2拷贝 2切换 ) sendFile 是 Linux 提供的函数 , 其在 Linux 2.4 版本中 , 直接将数据从 内核缓冲区 拷贝到 协议栈 中 ; 此次优化 , 由原来的

    94410

    【Linux 内核 内存管理】mmap 系统调用源码分析 ④ ( do_mmap 函数执行流程 | do_mmap 函数源码 )

    文章目录 一、do_mmap 函数执行流程 二、do_mmap 函数源码 调用 mmap 系统调用 , 先检查 " 偏移 " 是否是 " 内存页大小 " 的 " 整数倍 " , 如果偏移是内存页大小的整数倍..., 则调用 sys_mmap_pgoff 函数 , 继续向下执行 ; 在 sys_mmap_pgoff 系统调用函数 中 , 最后调用了 vm_mmap_pgoff 函数 , 继续向下执行 ; 在 vm_mmap_pgoff...函数 中 , 核心处理过程就是调用 do_mmap 函数 , 这是 " 内存映射 " 创建的主要函数逻辑 ; 一、do_mmap 函数执行流程 ---- do_mmap 函数 , 主要功能是 创建 "..." 内存映射 " 主要是 do_mmap 函数实现的 , 该函数定义在 Linux 内核源码的 linux-4.12\mm\mmap.c#1320 位置 ; do_mmap 函数源码如下 : /*...(flags & (MAP_POPULATE | MAP_NONBLOCK)) == MAP_POPULATE)) *populate = len; return addr; } 源码路径 : linux

    2.1K10

    Linux内存管理之mmap详解

    作者:freeboy1015 来源:http://lib.csdn.net/article/linux/62126 一. mmap系统调用 1. mmap系统调用 mmap将一个文件或者其它对象映射进内存...系统调用mmap()用于共享内存的两种方式 (1)使用普通文件提供的内存映射:适用于任何进程之间;此时,需要打开或创建一个文件,然后再调用mmap();典型调用代码如下: fd=open(name,...三. mmap进行内存映射的原理 mmap系统调用的最终目的是将,设备或文件映射到用户进程的虚拟地址空间,实现用户进程对文件的直接读写,这个任务可以分为以下三步: 1.在用户虚拟地址空间中寻找空闲的满足要求的一段连续的虚拟地址空间...下面是struct vm_area_struct结构体的定义: #include linux/mm_types.h> /* This struct defines a memory VMM memory...结构的成员: int (*mmap)(struct file *,struct vm_area_struct *); linux有2个方法建立页表: (1) 使用remap_pfn_range一次建立所有页表

    4.5K90

    【Netty】mmap 和 sendFile 零拷贝原理

    文章目录 一、 零拷贝 简介 二、 传统 BIO 数据拷贝分析 ( 4拷贝 4切换 ) 三、 mmap 内存映射 ( 3拷贝 4切换 ) 四、 sendFile 函数 ( Linux 2.1 优化 )..., 使用零拷贝能极大的提升数据传输性能 ; 零拷贝类型 : mmap ( 内存映射 ) 和 sendFile; 数据角度分析 : 在零拷贝机制中 , 整个数据在内存中只有一份数据 , 非零拷贝机制中...4切换 ) ---- 将硬盘中的文件映射到 内核缓冲区 , 用户空间中的应用程序也可以访问该 内核缓冲区 中的数据 , 使用这种机制 , 原来的 4 次数据拷贝减少到了 3 次 , 1 . mmap...-> 协议栈 : Socket 缓冲区 数据 , 通过 DMA 拷贝到 协议栈 ; 硬盘文件 -> 内核缓冲区 ( 内核空间 ) -> Socket 缓冲区 ( 内核空间 ) -> 协议栈 2 . mmap...2.4 优化 ) ( 2拷贝 2切换 ) ---- sendFile 是 Linux 提供的函数 , 其在 Linux 2.4 版本中 , 直接将数据从 内核缓冲区 拷贝到 协议栈 中 ; 此次优化

    72310

    Linux内存管理之mmap详解

    作者:freeboy1015 来源:http://lib.csdn.net/article/linux/62126 一. mmap系统调用 1. mmap系统调用 mmap将一个文件或者其它对象映射进内存...系统调用mmap()用于共享内存的两种方式 (1)使用普通文件提供的内存映射:适用于任何进程之间;此时,需要打开或创建一个文件,然后再调用mmap();典型调用代码如下: fd=open(name, flag...三. mmap进行内存映射的原理 mmap系统调用的最终目的是将,设备或文件映射到用户进程的虚拟地址空间,实现用户进程对文件的直接读写,这个任务可以分为以下三步: 1.在用户虚拟地址空间中寻找空闲的满足要求的一段连续的虚拟地址空间...,为映射做准备(由内核mmap系统调用完成) 每个进程拥有3G字节的用户虚存空间。...结构的成员: int (*mmap)(struct file *,struct vm_area_struct *); linux有2个方法建立页表: (1) 使用remap_pfn_range一次建立所有页表

    2.6K40

    【Linux 内核 内存管理】mmap 系统调用源码分析 ③ ( vm_mmap_pgoff 函数执行流程 | vm_mmap_pgoff 函数源码 )

    文章目录 一、vm_mmap_pgoff 函数执行流程 二、vm_mmap_pgoff 函数源码 调用 mmap 系统调用 , 先检查 " 偏移 " 是否是 " 内存页大小 " 的 " 整数倍 " ,...如果偏移是内存页大小的整数倍 , 则调用 sys_mmap_pgoff 函数 , 继续向下执行 ; 在 sys_mmap_pgoff 系统调用函数 中 , 最后调用了 vm_mmap_pgoff 函数..., 继续向下执行 ; 一、vm_mmap_pgoff 函数执行流程 ---- 在 vm_mmap_pgoff 函数中 , 首先 , 以 " 写者 " 身份 , 向 Linux 内核申请 读写 " 信号量...函数源码 ---- vm_mmap_pgoff 函数定义在 Linux 内核源码中的 linux-4.12\mm\util.c#296 位置 ; vm_mmap_pgoff 函数源码如下 : unsigned...(mm, &uf); if (populate) mm_populate(ret, populate); } return ret; } 源码路径 : linux-4.12\mm\util.c

    2.2K10

    Android中mmap原理及应用简析

    mmap是Linux中常用的系统调用API,用途广泛,Android中也有不少地方用到,比如匿名共享内存,Binder机制等。本文简单记录下Android中mmap调用流程及原理。...mmap->mmap64->__mmap2->sys_mmap2-> sys_mmap_pgoff ->do_mmap_pgoff /Users/personal/source_code/android...Binder mmap 的作用及原理(一次拷贝) Binder机制中mmap的最大特点是一次拷贝即可完成进程间通信。...Linux的内存分用户空间跟内核空间,同时页表有也分两类,用户空间页表跟内核空间页表,每个进程有一个用户空间页表,但是系统只有一个内核空间页表。...普通文件mmap原理 普通文件的访问方式有两种:第一种是通过read/write系统调访问,先在用户空间分配一段buffer,然后,进入内核,将内容从磁盘读取到内核缓冲,最后,拷贝到用户进程空间,至少牵扯到两次数据拷贝

    1.9K40

    【Linux 内核 内存管理】mmap 系统调用源码分析 ⑤ ( mmap_region 函数执行流程 | mmap_region 函数源码 )

    文章目录 一、mmap_region 函数执行流程 1、检查内存申请是否合法 2、创建 " 虚拟内存区域 " 二、mmap_region 函数源码 调用 mmap 系统调用 , 先检查 " 偏移 "...; 在 do_mmap 函数中 , 调用了 mmap_region 函数 , 创建 " 虚拟内存区域 " ; 一、mmap_region 函数执行流程 ---- 1、检查内存申请是否合法 在 mmap_region...may_expand_vm(mm, vm_flags, (len >> PAGE_SHIFT) - nr_pages)) return -ENOMEM; } 源码路径 : linux-..., prev, rb_link, rb_parent); 源码路径 : linux-4.12\mm\mmap.c#1710 vma_set_page_prot(vma); 源码路径 : linux-4.12...\mm\mmap.c#1743 二、mmap_region 函数源码 ---- mmap_region 函数源码 定义在 Linux 内核源码的 linux-4.12\mm\mmap.c#1602 位置

    1.9K20

    韦东山:Linux驱动程序基石之mmap

    二级页表地址旺射的最小单位有4K、1K,Linux使用4K。 一级页表项里的内容,决定了它是指向一块物理内存,还是指问二级页表,如下图: ?...程序运行时有“局部性原理”,这又分为时间局部性、空间局部性。 ① 时间局部性: 在某个时间点访问了存储器的特定位置,很可能在一小段时间里,会反复地访问这个位置。...根据“局部性原理”,可以引入cache。 ① 读取内存addr处的数据时: 先看看cache中有没有addr的数据,如果有就直接从cache里返回数据:这被称为cache命中。...是否使用cache、是否使用buffer,就有4种组合(Linux内核文件arch\arm\include\asm\pgtable-2level.h): ?...3.3, 驱动程序要做的事 驱动程序要做的事情有3点: ① 确定物理地址 ② 确定属性:是否使用cache、buffer ③ 建立映射关系 参考Linux源文件,示例代码如下: ?

    7K40

    韦东山:Linux驱动程序基石之mmap

    二级页表地址旺射的最小单位有4K、1K,Linux使用4K。...程序运行时有“局部性原理”,这又分为时间局部性、空间局部性。 ① 时间局部性: 在某个时间点访问了存储器的特定位置,很可能在一小段时间里,会反复地访问这个位置。...根据“局部性原理”,可以引入cache。 ① 读取内存addr处的数据时: 先看看cache中有没有addr的数据,如果有就直接从cache里返回数据:这被称为cache命中。...是否使用cache、是否使用buffer,就有4种组合(Linux内核文件arch\arm\include\asm\pgtable-2level.h): 第1种是不使用cache也不使用buffer,...3.3, 驱动程序要做的事 驱动程序要做的事情有3点: ① 确定物理地址 ② 确定属性:是否使用cache、buffer ③ 建立映射关系 参考Linux源文件,示例代码如下: 还有一个更简单的函数:

    4.1K31

    Linux的内存共享映射(mmap和munmap)

    Linux下的进程间通信也可以使用mmap的内存共享映射来实现,mmap的作用就是把磁盘文件的一部分直接映射到进程的内存中,那么进程就可以直接对该内存文件进行操作,mmap也设置了两种机制...通过这样的内存共享映射就相当于是进程直接对磁盘中的文件进行读写操作一样,那么如果有两个进程来mmap同一个文件,就实现了进程间的通信。...磁盘中的文件通过mmap函数来实现映射,然后通过munmap函数取消映射。...先来看一下函数的原型: #include void *mmap(void *addr, size_t length, int prot, int flags, int fd,...如果在运行中出现Bus error (core dumped)错误,需要考虑共享文件是否有存储空间(也就是说你要mmap一个4096的文件,但实际文件没有4096那么大)。

    8.3K30
    领券