0

0

C++大内存如何分配 内存映射文件技术

P粉602998670

P粉602998670

发布时间:2025-08-21 11:20:01

|

968人浏览过

|

来源于php中文网

原创

内存映射文件通过将文件直接映射到进程地址空间,避免传统I/O的数据拷贝开销,支持高效的大文件访问与共享。Windows使用CreateFileMapping和MapViewOfFile,Linux使用mmap实现。其优势包括节省物理内存、避免堆碎片、支持超大文件和进程间共享,适用于大日志检索、数据库加载、多媒体处理等场景。需注意资源释放、数据同步、虚拟内存耗尽及多线程同步问题。

c++大内存如何分配 内存映射文件技术

在C++中处理大内存分配时,传统的

malloc
new
可能会受到进程虚拟地址空间碎片、系统内存限制或性能问题的制约。当需要操作几百MB甚至GB级别的数据时,内存映射文件(Memory-Mapped Files)是一种高效且实用的技术。它通过将文件直接映射到进程的地址空间,实现对大内存的高效访问和管理。

什么是内存映射文件

内存映射文件是一种将磁盘上的文件内容直接映射到进程虚拟内存的技术。操作系统负责在需要时将文件的某些页加载到物理内存,并在内存压力大时将其换出。对程序来说,这部分数据就像普通的内存一样,可以用指针直接读写。

这种方式避免了传统I/O中

read
/
write
系统调用带来的数据拷贝开销,特别适合大文件的随机访问或多个进程共享数据的场景。

在C++中使用内存映射文件

内存映射文件的使用在不同操作系统上略有差异,下面分别介绍Windows和Linux下的实现方式。

立即学习C++免费学习笔记(深入)”;

Windows平台

Windows提供了一组API来支持内存映射文件:

  • CreateFile
    :打开文件
  • CreateFileMapping
    :创建文件映射对象
  • MapViewOfFile
    :将文件映射到内存

示例代码:

EduPro
EduPro

EduPro - 留学行业的AI工具箱

下载
#include 
#include 

int main() { HANDLE hFile = CreateFile(L"largefile.dat", GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile == INVALID_HANDLE_VALUE) { std::cerr << "无法打开文件\n"; return 1; }

HANDLE hMapping = CreateFileMapping(hFile, nullptr, PAGE_READWRITE, 0, 1024 * 1024 * 1024, nullptr); // 映射1GB
if (!hMapping) {
    std::cerr << "无法创建映射\n";
    CloseHandle(hFile);
    return 1;
}

char* pData = static_cast(MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0));
if (!pData) {
    std::cerr << "无法映射视图\n";
    CloseHandle(hMapping);
    CloseHandle(hFile);
    return 1;
}

// 直接访问内存
pData[0] = 'H';
pData[1] = 'i';

// 清理
UnmapViewOfFile(pData);
CloseHandle(hMapping);
CloseHandle(hFile);

return 0;

}

Linux/Unix平台

Linux使用

mmap
系统调用来实现内存映射。

  • open
    :打开文件
  • mmap
    :映射文件到内存
  • munmap
    :解除映射

示例代码:

#include 
#include 
#include 
#include 
#include 
#include 

int main() { int fd = open("largefile.dat", O_RDWR | O_CREAT, 0666); if (fd == -1) { perror("open"); return 1; }

const size_t fileSize = 1UL << 30; // 1GB
// 扩展文件大小
lseek(fd, fileSize - 1, SEEK_SET);
write(fd, "", 1);

char* pData = static_cast(mmap(nullptr, fileSize, PROT_READ | PROT_WRITE,
                                      MAP_SHARED, fd, 0));
if (pData == MAP_FAILED) {
    perror("mmap");
    close(fd);
    return 1;
}

// 使用映射内存
pData[0] = 'H';
pData[1] = 'i';

// 同步到磁盘
msync(pData, fileSize, MS_SYNC);

// 解除映射
munmap(pData, fileSize);
close(fd);

return 0;

}

内存映射的优势与适用场景

相比直接使用

new
malloc
分配大内存,内存映射文件有以下优势:

  • 节省物理内存:只有访问的页面才会被加载到内存,未访问部分不会占用RAM
  • 避免内存碎片:映射的是虚拟地址空间,不依赖堆的连续性
  • 高效I/O:省去用户态与内核态之间的数据拷贝
  • 进程间共享:多个进程可映射同一文件,实现共享内存通信
  • 支持超大文件:即使文件大于可用内存,也能分页访问

常见应用场景包括:

  • 大日志文件的快速检索
  • 数据库索引或数据文件的加载
  • 图像、视频等大型二进制文件处理
  • 进程间大数据共享

注意事项与最佳实践

使用内存映射文件时需注意以下几点:

  • 映射失败时要正确释放资源,避免句柄泄漏
  • 及时调用
    msync
    (Linux)或
    FlushViewOfFile
    (Windows)确保数据写入磁盘
  • 避免映射过大的文件导致虚拟地址空间耗尽(尤其在32位系统)
  • 多线程访问时需自行加锁,系统不提供同步机制
  • 映射区域的大小必须是页大小的整数倍(通常4KB)

基本上就这些。内存映射文件是处理大内存需求时的强大工具,合理使用可以显著提升程序性能和稳定性。

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

371

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

563

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

472

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

109

2025.12.24

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

521

2023.07.26

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1055

2023.07.27

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

751

2023.08.01

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

420

2023.08.02

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

74

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 5.8万人学习

C 教程
C 教程

共75课时 | 3.8万人学习

C++教程
C++教程

共115课时 | 10.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号