使用mmap优化大文件处理的内存占用问题求助
问题原因
你当前的代码一次性将整个20GB文件映射到内存,虽然mmap本身不会立即分配物理内存,但当你顺序遍历所有数据时,内核会把每个访问过的页面加载到物理内存并缓存起来,最终导致整个文件都驻留在内存中,占用20GB空间。
解决方案
要把内存消耗控制在1GB左右,核心思路是分块映射文件:每次只映射文件中1GB左右的片段,处理完该片段后立即解除映射,让内核回收这部分内存,再处理下一块。
需要注意几个关键点:
- 映射的偏移和长度必须对齐到系统页大小(通常是4KB或8KB),可通过
sysconf(_SC_PAGESIZE)获取页大小。 - 文件总大小可能不是1GB的整数倍,最后一块需按实际剩余大小处理。
- 每块处理完成后必须调用
munmap释放映射区域,避免内存泄漏。
修改后的示例代码
#include <iostream> #include <string> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <cstdlib> int main() { std::string srcPath = "srcList.bin"; int srcFd = open(srcPath.c_str(), O_RDONLY); if (srcFd == -1) { perror("open"); return EXIT_FAILURE; } struct stat sb; if (fstat(srcFd, &sb) == -1) { perror("fstat"); close(srcFd); return EXIT_FAILURE; } off_t total_bytes = sb.st_size; const size_t page_size = sysconf(_SC_PAGESIZE); // 设置每块映射大小为1GB,并对齐到页大小 const size_t block_bytes = 1024 * 1024 * 1024; const size_t aligned_block_bytes = (block_bytes + page_size - 1) & ~(page_size - 1); for (off_t offset = 0; offset < total_bytes; offset += aligned_block_bytes) { // 计算当前块的实际大小(最后一块可能小于1GB) size_t current_block_bytes = std::min(static_cast<size_t>(total_bytes - offset), aligned_block_bytes); // 映射当前块 int64_t* block_addr = static_cast<int64_t*>(mmap(nullptr, current_block_bytes, PROT_READ, MAP_SHARED, srcFd, offset)); if (block_addr == MAP_FAILED) { perror("mmap"); close(srcFd); return EXIT_FAILURE; } // 计算当前块的int64_t元素数量(每个元素占8字节) size_t element_count = current_block_bytes / sizeof(int64_t); // 处理当前块的元素 for (size_t i = 0; i < element_count; ++i) { int64_t tmp = block_addr[i]; // do something } // 解除当前块的映射,释放内存 if (munmap(block_addr, current_block_bytes) == -1) { perror("munmap"); close(srcFd); return EXIT_FAILURE; } } close(srcFd); return EXIT_SUCCESS; }
额外说明
- 映射模式选择:如果只是读取文件,
MAP_SHARED和MAP_PRIVATE都可以,只读场景下两者差异不大,核心还是分块映射逻辑。 - 页对齐必要性:
mmap要求映射的偏移和长度必须是页大小的整数倍,否则会触发错误,代码中已对块大小做了对齐处理。 - 原代码修正:你原本的循环条件
i < srcLength是错误的——srcLength是文件字节数,而srcAddr[i]是按int64_t元素索引,正确逻辑应该是按元素数量遍历,修改后的代码已修复该问题。
内容的提问来源于stack exchange,提问作者YA xiang
相关产品推荐
相关产品推荐

