You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

只读映射超大文件时mmap调用报ENOMEM错误,求解决方法

问题:240GiB只读文件mmap失败(Errno=9)

复现代码

#include <stdio.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

void main() {
        int fd = open("file.data", O_RDONLY);
        void* ptr = mmap(0, (size_t)240 * 1024 * 1024 * 1024, PROT_READ, MAP_SHARED, fd, 0);
        printf("Result = %p\n", ptr);
        printf("Errno = %d\n", errno);
}

编译运行命令

gcc test.c && ./a.out

运行输出

Result = 0xffffffffffffffff
Errno = 9

目标文件信息

file.data是一个243 GiB的文件,其stat信息如下:

$ stat file.data
  File: file.data
  Size: 260165023654    Blocks: 508135088  IO Block: 4096   regular file
Device: 801h/2049d      Inode: 6815790     Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1001/  user)   Gid: ( 1001/  user)
Access: 2023-05-08 09:22:07.314477587 -0400
Modify: 2023-06-16 07:53:12.275187040 -0400
Change: 2023-06-16 07:53:12.275187040 -0400
 Birth: -

系统配置及参数

系统为Debian Stretch、Linux 5.2.21,相关参数如下:

内存超额配置设置

$ sysctl vm.overcommit_memory
vm.overcommit_memory = 1

资源限制

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 768178
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 768178
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

内存状态

$ free -m
              total        used        free      shared  buff/cache   available
Mem:         192105         671      189213           9        2220      190314
Swap:             0           0           0

已尝试的优化措施

  • 未使用MAP_PRIVATE+PROT_WRITE的映射组合
  • 已将ulimit -v设为unlimited
  • 已设置vm.overcommit_memory=1

疑问与诉求

按道理这个只读mmap应该能成功:内核可以随时将映射页换出到磁盘,而且64位系统应该有足够的连续虚拟地址空间。请问如何让mmap调用成功?

程序的/proc/*/maps输出

2aaaaaa000-2aaaaab000 r-xp 00000000 08:01 6815754                        /home/<username>/a.out
2aaacaa000-2aaacab000 r--p 00000000 08:01 6815754                        /home/<username>/a.out
2aaacab000-2aaacac000 rw-p 00001000 08:01 6815754                        /home/<username>/a.out
3ff7a3a000-3ff7bcf000 r-xp 00000000 08:01 5767499                        /lib/x86_64-linux-gnu/libc-2.24.so
3ff7bcf000-3ff7dcf000 ---p 00195000 08:01 5767499                        /lib/x86_64-linux-gnu/libc-2.24.so
3ff7dcf000-3ff7dd3000 r--p 00195000 08:01 5767499                        /lib/x86_64-linux-gnu/libc-2.24.so
3ff7dd3000-3ff7dd5000 rw-p 00199000 08:01 5767499                        /lib/x86_64-linux-gnu/libc-2.24.so
3ff7dd5000-3ff7dd9000 rw-p 00000000 00:00 0
3ff7dd9000-3ff7dfc000 r-xp 00000000 08:01 5767249                        /lib/x86_64-linux-gnu/ld-2.24.so
3ff7fe8000-3ff7fea000 rw-p 00000000 00:00 0
3ff7ff8000-3ff7ffb000 r--p 00000000 00:00 0                              [vvar]
3ff7ffb000-3ff7ffc000 r-xp 00000000 00:00 0                              [vdso]
3ff7ffc000-3ff7ffd000 r--p 00023000 08:01 5767249                        /lib/x86_64-linux-gnu/ld-2.24.so
3ff7ffd000-3ff7ffe000 rw-p 00024000 08:01 5767249                        /lib/x86_64-linux-gnu/ld-2.24.so
3ff7ffe000-3ff7fff000 rw-p 00000000 00:00 0
3ffffde000-3ffffff000 rw-p 00000000 00:00 0                              [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

内容的提问来源于stack exchange,提问作者cmpxchg8b

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 13:55:03