mmap 匿名映射

mmap 匿名文件映射的主要作用是返回一段指定大小的虚拟地址空间。

1. mmap 匿名映射的核心作用

当使用mmap进行匿名映射时(即不关联实际文件,通过MAP_ANONYMOUS标志创建),操作系统会:

  1. 在进程的虚拟地址空间中分配一段连续的区域
  2. 将这段地址空间映射到物理内存(按需分配,可能延迟分配)
  3. 返回指向该虚拟地址空间起始位置的指针

这个过程类似于调用malloc分配内存,但有几个重要区别:

特性mmap 匿名映射malloc
底层实现直接调用内存映射机制基于 brk 或 mmap(大块内存)
分配粒度按页分配(通常 4KB 或更大)按请求大小分配(更灵活)
释放方式必须显式调用 munmap自动管理(free)
内存连续性保证虚拟地址连续虚拟地址连续
初始内容全零可能包含垃圾数据(需初始化)
适用场景大内存块、跨进程共享中小内存块、频繁分配释放

2. 典型应用场景

  1. 大内存块分配:当需要分配超过 128KB 的内存时,mmap 通常比 malloc 更高效(避免内存碎片)
  2. 进程间共享内存:结合MAP_SHARED标志,多个进程可访问同一块物理内存
  3. 延迟分配优化:利用 Linux 的 "请求调页" 机制,实际物理内存仅在访问时分配
  4. 内存映射文件替代:当不需要持久化存储时,匿名映射比文件映射更简洁

3. 示例代码

以下是使用 mmap 创建匿名映射的基本示例:

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>

int main() {
    size_t size = 1024 * 1024; // 1MB
    void *ptr = mmap(
        NULL,                 // 让系统选择地址
        size,                 // 映射大小
        PROT_READ | PROT_WRITE, // 可读可写
        MAP_ANONYMOUS | MAP_PRIVATE, // 匿名私有映射
        -1,                   // 不关联文件
        0                     // 偏移量
    );
    
    if (ptr == MAP_FAILED) {
        perror("mmap failed");
        return 1;
    }
    
    // 使用内存
    for (int i = 0; i < 1024; i++) {
        ((char*)ptr)[i] = 'A';
    }
    
    // 释放内存
    if (munmap(ptr, size) == -1) {
        perror("munmap failed");
        return 1;
    }
    
    return 0;
}

4. 关键特性说明

  • 虚拟地址保证:mmap 返回的地址空间是连续的虚拟地址,但物理内存可能不连续(通过页表映射实现)
  • 零初始化:匿名映射的内存默认初始化为零(不同于 malloc)
  • 内存释放:必须显式调用 munmap 释放,否则会导致内存泄漏
  • 权限控制:通过PROT_*标志可精确控制内存访问权限(如只读、可执行等)

5.用户空间与 GPU 内存的映射

GPU 驱动需要将物理显存(VRAM)或系统内存映射到用户空间,使应用程序能够直接访问

  • 零拷贝数据传输:通过MAP_SHARED标志,用户空间缓冲区可直接被 GPU 访问,避免数据在用户空间和内核空间之间的复制
  • 显存管理:将 VRAM 区域映射到用户空间,实现高效的图形数据读写

这种机制为高性能应用提供了灵活且高效的内存管理方式,尤其适合需要大块连续内存或跨进程数据共享的场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值