gpt4 book ai didi

c - mmap 返回 ENOMEM

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:18:35 24 4
gpt4 key购买 nike

我阅读了与该主题相关的所有帖子,但没有找到任何能够解决我的问题的内容。

我正在尝试映射一个由基础文件支持的 900Mb MAP_SHARED。我们有 2Gb 的 RAM 和只有 2Gb 的虚拟内存可用(1Gb 保留给内核 + 1Gb 保留给管理程序)。

ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);

我在考虑缺少可用的 VMEM,所以我尝试输入“sysctl -w vm.overcommit_memory=1”,但它也失败了。

我做了一个小循环(如下)来了解 mmap 在多大时真正失败,我发现它接近 700Mb,所以它在高达 700Mb 时工作正常,然后失败。

ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
if ((MAP_FAILED == ptr) && (errno == ENOMEM)) {
for (i = 0; i < 16; i++) {
ptr = mmap(NULL, size / 16, PROT_READ, MAP_SHARED, fd, (size / 16) * i);
if (MAP_FAILED == ptr) {
printf("map num:%d failed errno:%d", i, errno);
break;
}
}

感谢您的帮助。

PS:shm_open 和 ftruncate 没有返回任何错误。 ftruncate 和 mmap 使用相同的大小。

free -m 返回 Swap 0 0 0。


编辑 1:显然,我在 VMEM 中没有 900Mb 的连续空间,就像我用小 mmap 说的那样,一步一步地,我能够达到 ~720Mo 的 mmap,但我没有找到解决这个连续限制的方法。我是否必须将它拆分为多个文件描述符或类似的东西?


编辑 2:

有了一些 shmem 大小的改进,我现在可以 mmap(870Mb),几乎就可以了 :D但我不明白为什么堆和第一个库之间有 ~880Mb 的巨大差距,有人给我提示吗?

proc/$PID/maps 的结果下方

08048000-08081000 r-xp 00000000 08:02 2564       /usr/bin/myapp
08081000-0820a000 rw-p 00038000 08:02 2564 /usr/bin/myapp
0820a000-09151000 rwxp 00000000 00:00 0 [heap]
40000000-40022000 r-xp 00000000 08:02 14697 /lib/ld-2.22.so
40022000-40023000 r--p 00021000 08:02 14697 /lib/ld-2.22.so
40023000-40024000 rw-p 00022000 08:02 14697 /lib/ld-2.22.so
40024000-40025000 rw-p 00000000 00:00 0
40027000-40040000 r-xp 00000000 08:02 14692 /lib/libpthread-2.22.so
40040000-40041000 r--p 00018000 08:02 14692 /lib/libpthread-2.22.so
40041000-40042000 rw-p 00019000 08:02 14692 /lib/libpthread-2.22.so
40042000-40044000 rw-p 00000000 00:00 0
40044000-4004b000 r-xp 00000000 08:02 14686 /lib/librt-2.22.so
4004b000-4004c000 r--p 00006000 08:02 14686 /lib/librt-2.22.so
4004c000-4004d000 rw-p 00007000 08:02 14686 /lib/librt-2.22.so
4004d000-401b2000 r-xp 00000000 08:02 39034 /usr/lib/libxml2.so.2.9.2
401b2000-401b7000 rw-p 00164000 08:02 39034 /usr/lib/libxml2.so.2.9.2
401b7000-401b8000 rw-p 00000000 00:00 0
401b8000-40368000 r-xp 00000000 08:02 14699 /lib/libc-2.22.so
40368000-40369000 ---p 001b0000 08:02 14699 /lib/libc-2.22.so
40369000-4036b000 r--p 001b0000 08:02 14699 /lib/libc-2.22.so
4036b000-4036c000 rw-p 001b2000 08:02 14699 /lib/libc-2.22.so
4036c000-4036f000 rw-p 00000000 00:00 0
4036f000-40372000 r-xp 00000000 08:02 14881 /lib/libdl-2.22.so
40372000-40373000 r--p 00002000 08:02 14881 /lib/libdl-2.22.so
40373000-40374000 rw-p 00003000 08:02 14881 /lib/libdl-2.22.so
40374000-40375000 rw-p 00000000 00:00 0
40375000-4038a000 r-xp 00000000 08:02 14698 /lib/libz.so.1.2.8
4038a000-4038b000 rw-p 00015000 08:02 14698 /lib/libz.so.1.2.8
4038b000-403d6000 r-xp 00000000 08:02 14664 /lib/libm-2.22.so
403d6000-403d7000 r--p 0004a000 08:02 14664 /lib/libm-2.22.so
403d7000-403d8000 rw-p 0004b000 08:02 14664 /lib/libm-2.22.so
403d8000-403da000 rw-p 00000000 00:00 0
403da000-40b6a000 rw-s 17180000 00:05 2845 /dev/vmfileshm20
40b6a000-40b6b000 ---p 00000000 00:00 0
40b6b000-4136b000 rw-p 00000000 00:00 0
4136b000-4156c000 rw-s 17a00000 00:05 2758 /dev/vmfileshm12
4156c000-4176d000 rw-s 17c80000 00:05 2801 /dev/vmfileshm16
4176d000-4176e000 ---p 00000000 00:00 0
4176e000-41f6e000 rw-p 00000000 00:00 0
41f6e000-42e6f000 rw-s 17f00000 00:05 2670 /dev/vmfileshm4
42f00000-42f21000 rw-p 00000000 00:00 0
42f21000-43000000 ---p 00000000 00:00 0
43000000-43021000 rw-p 00000000 00:00 0
43021000-43100000 ---p 00000000 00:00 0
43100000-44001000 rw-s 1ad80000 00:05 2713 /dev/vmfileshm8
44001000-44002000 ---p 00000000 00:00 0
44002000-44802000 rw-p 00000000 00:00 0
44802000-449ff000 rw-s 1d300000 00:05 2890 /dev/vmfileshm24
449ff000-44a00000 ---p 00000000 00:00 0
44a00000-45200000 rw-p 00000000 00:00 0
45200000-45201000 ---p 00000000 00:00 0
45201000-45a01000 rw-p 00000000 00:00 0
45a01000-47570000 rw-s 1d780000 00:05 2933 /dev/vmfileshm28
47570000-47aef000 rw-s 28380000 00:05 2967 /dev/vmfileshm31
47aef000-47af0000 ---p 00000000 00:00 0
47af0000-482f0000 rw-p 00000000 00:00 0
482f0000-490e1000 r--s 2c480000 00:05 3025 /dev/vmfileshm37
490e1000-49ed2000 r--s 2c480000 00:05 3025 /dev/vmfileshm37
49ed2000-4acc3000 r--s 2c481000 00:05 3025 /dev/vmfileshm37
4acc3000-4bab4000 r--s 2c482000 00:05 3025 /dev/vmfileshm37
4bab4000-4c8a5000 r--s 2c483000 00:05 3025 /dev/vmfileshm37
4c8a5000-4d696000 r--s 2c484000 00:05 3025 /dev/vmfileshm37
4d696000-4e487000 r--s 2c485000 00:05 3025 /dev/vmfileshm37
4e487000-4f278000 r--s 2c486000 00:05 3025 /dev/vmfileshm37
4f278000-50069000 r--s 2c486000 00:05 3025 /dev/vmfileshm37
50069000-50e5a000 r--s 2c487000 00:05 3025 /dev/vmfileshm37
50e5a000-51c4b000 r--s 2c488000 00:05 3025 /dev/vmfileshm37
51c4b000-52a3c000 r--s 2c489000 00:05 3025 /dev/vmfileshm37
52a3c000-5382d000 r--s 2c48a000 00:05 3025 /dev/vmfileshm37
5382d000-5461e000 r--s 2c48b000 00:05 3025 /dev/vmfileshm37
5461e000-5540f000 r--s 2c48c000 00:05 3025 /dev/vmfileshm37
5540f000-56200000 r--s 2c48d000 00:05 3025 /dev/vmfileshm37
56200000-56ff1000 r--s 2c48d000 00:05 3025 /dev/vmfileshm37
56ff1000-57de2000 r--s 2c48e000 00:05 3025 /dev/vmfileshm37
57de2000-58bd3000 r--s 2c48f000 00:05 3025 /dev/vmfileshm37
58bd3000-599c4000 r--s 2c490000 00:05 3025 /dev/vmfileshm37
599c4000-5a7b5000 r--s 2c491000 00:05 3025 /dev/vmfileshm37
5a7b5000-5b5a6000 r--s 2c492000 00:05 3025 /dev/vmfileshm37
5b5a6000-5c397000 r--s 2c493000 00:05 3025 /dev/vmfileshm37
5c397000-5d188000 r--s 2c494000 00:05 3025 /dev/vmfileshm37
5d188000-5df79000 r--s 2c494000 00:05 3025 /dev/vmfileshm37
5df79000-5ed6a000 r--s 2c495000 00:05 3025 /dev/vmfileshm37
5ed6a000-5fb5b000 r--s 2c496000 00:05 3025 /dev/vmfileshm37
5fb5b000-6094c000 r--s 2c497000 00:05 3025 /dev/vmfileshm37
6094c000-6173d000 r--s 2c498000 00:05 3025 /dev/vmfileshm37
6173d000-6252e000 r--s 2c499000 00:05 3025 /dev/vmfileshm37
6252e000-6331f000 r--s 2c49a000 00:05 3025 /dev/vmfileshm37
6331f000-64110000 r--s 2c49b000 00:05 3025 /dev/vmfileshm37
64110000-64f01000 r--s 2c49b000 00:05 3025 /dev/vmfileshm37
64f01000-65cf2000 r--s 2c49c000 00:05 3025 /dev/vmfileshm37
65cf2000-66ae3000 r--s 2c49d000 00:05 3025 /dev/vmfileshm37
66ae3000-678d4000 r--s 2c49e000 00:05 3025 /dev/vmfileshm37
678d4000-686c5000 r--s 2c49f000 00:05 3025 /dev/vmfileshm37
686c5000-694b6000 r--s 2c4a0000 00:05 3025 /dev/vmfileshm37
694b6000-6a2a7000 r--s 2c4a1000 00:05 3025 /dev/vmfileshm37
6a2a7000-6b098000 r--s 2c4a1000 00:05 3025 /dev/vmfileshm37
6b098000-6be89000 r--s 2c4a2000 00:05 3025 /dev/vmfileshm37
6be89000-6cc7a000 r--s 2c4a3000 00:05 3025 /dev/vmfileshm37
6cc7a000-6da6b000 r--s 2c4a4000 00:05 3025 /dev/vmfileshm37
6da6b000-6e85c000 r--s 2c4a5000 00:05 3025 /dev/vmfileshm37
6e85c000-6f64d000 r--s 2c4a6000 00:05 3025 /dev/vmfileshm37
6f64d000-7043e000 r--s 2c4a7000 00:05 3025 /dev/vmfileshm37
7043e000-7122f000 r--s 2c4a8000 00:05 3025 /dev/vmfileshm37
7122f000-72020000 r--s 2c4a8000 00:05 3025 /dev/vmfileshm37
72020000-72e11000 r--s 2c4a9000 00:05 3025 /dev/vmfileshm37
72e11000-73c02000 r--s 2c4aa000 00:05 3025 /dev/vmfileshm37
73c02000-749f3000 r--s 2c4ab000 00:05 3025 /dev/vmfileshm37
749f3000-757e4000 r--s 2c4ac000 00:05 3025 /dev/vmfileshm37
757e4000-765d5000 r--s 2c4ad000 00:05 3025 /dev/vmfileshm37
765d5000-773c6000 r--s 2c4ae000 00:05 3025 /dev/vmfileshm37
773c6000-781b7000 r--s 2c4af000 00:05 3025 /dev/vmfileshm37
781b7000-78fa8000 r--s 2c4af000 00:05 3025 /dev/vmfileshm37
78fa8000-79d99000 r--s 2c4b0000 00:05 3025 /dev/vmfileshm37
79d99000-7ab8a000 r--s 2c4b1000 00:05 3025 /dev/vmfileshm37
7ab8a000-7b97b000 r--s 2c4b2000 00:05 3025 /dev/vmfileshm37
7b97b000-7c76c000 r--s 2c4b3000 00:05 3025 /dev/vmfileshm37
7c76c000-7d55d000 r--s 2c4b4000 00:05 3025 /dev/vmfileshm37
7d55d000-7e34e000 r--s 2c4b5000 00:05 3025 /dev/vmfileshm37
7e34e000-7f13f000 r--s 2c4b6000 00:05 3025 /dev/vmfileshm37
7f91e000-7f93f000 rw-p 00000000 00:00 0 [stack]
00000000-00000000 r-xp 00000000 00:00 0 [vdso]

编辑 3:现在我已经将所有小的共享内存(见下文)移动到堆之后,并将 >900Mb 的内存放在 lib 之上(以便为我的大共享内存提供最大可用空间)

08048000-08081000 r-xp 00000000 08:02 2652       /usr/bin/myapp
08081000-0820a000 rw-p 00038000 08:02 2652 /usr/bin/myapp
0820a000-09151000 rwxp 00000000 00:00 0 [heap]
0b001000-0b791000 rw-s 17180000 00:05 2655 /dev/shm20
0b791000-0b992000 rw-s 17a00000 00:05 2567 /dev/shm12
0b992000-0bb93000 rw-s 17c80000 00:05 2611 /dev/shm16
0bb93000-0ca94000 rw-s 17f00000 00:05 2479 /dev/shm4
0ca94000-0d995000 rw-s 19e00000 00:05 2523 /dev/shm8
0d995000-0db92000 rw-s 1ad80000 00:05 2700 /dev/shm24
0db92000-0f701000 rw-s 1b680000 00:05 2743 /dev/shm28
0f701000-0fc80000 rw-s 1eb80000 00:05 2776 /dev/shm31
40000000-40022000 r-xp 00000000 08:02 14697 /lib/ld-2.22.so
40022000-40023000 r--p 00021000 08:02 14697 /lib/ld-2.22.so
40023000-40024000 rw-p 00022000 08:02 14697 /lib/ld-2.22.so
40024000-40025000 rw-p 00000000 00:00 0
40027000-40040000 r-xp 00000000 08:02 14692 /lib/libpthread-2.22.so
40040000-40041000 r--p 00018000 08:02 14692 /lib/libpthread-2.22.so
40041000-40042000 rw-p 00019000 08:02 14692 /lib/libpthread-2.22.so
40042000-40044000 rw-p 00000000 00:00 0
40044000-4004b000 r-xp 00000000 08:02 14686 /lib/librt-2.22.so
4004b000-4004c000 r--p 00006000 08:02 14686 /lib/librt-2.22.so
4004c000-4004d000 rw-p 00007000 08:02 14686 /lib/librt-2.22.so
4004d000-401b2000 r-xp 00000000 08:02 39031 /usr/lib/libxml2.so.2.9.2
401b2000-401b7000 rw-p 00164000 08:02 39031 /usr/lib/libxml2.so.2.9.2
401b7000-401b8000 rw-p 00000000 00:00 0
401b8000-40368000 r-xp 00000000 08:02 14699 /lib/libc-2.22.so
40368000-40369000 ---p 001b0000 08:02 14699 /lib/libc-2.22.so
40369000-4036b000 r--p 001b0000 08:02 14699 /lib/libc-2.22.so
4036b000-4036c000 rw-p 001b2000 08:02 14699 /lib/libc-2.22.so
4036c000-4036f000 rw-p 00000000 00:00 0
4036f000-40372000 r-xp 00000000 08:02 14881 /lib/libdl-2.22.so
40372000-40373000 r--p 00002000 08:02 14881 /lib/libdl-2.22.so
40373000-40374000 rw-p 00003000 08:02 14881 /lib/libdl-2.22.so
40374000-40375000 rw-p 00000000 00:00 0
40375000-4038a000 r-xp 00000000 08:02 14698 /lib/libz.so.1.2.8
4038a000-4038b000 rw-p 00015000 08:02 14698 /lib/libz.so.1.2.8
4038b000-403d6000 r-xp 00000000 08:02 14664 /lib/libm-2.22.so
403d6000-403d7000 r--p 0004a000 08:02 14664 /lib/libm-2.22.so
403d7000-403d8000 rw-p 0004b000 08:02 14664 /lib/libm-2.22.so
403d8000-403da000 rw-p 00000000 00:00 0
403da000-403db000 ---p 00000000 00:00 0
403db000-40bdb000 rw-p 00000000 00:00 0
40bdb000-40bdc000 ---p 00000000 00:00 0
40bdc000-413dc000 rw-p 00000000 00:00 0
41400000-41421000 rw-p 00000000 00:00 0
41421000-41500000 ---p 00000000 00:00 0
41500000-41521000 rw-p 00000000 00:00 0
41521000-41600000 ---p 00000000 00:00 0
41600000-41601000 ---p 00000000 00:00 0
41601000-41e01000 rw-p 00000000 00:00 0
41e01000-41e02000 ---p 00000000 00:00 0
41e02000-42602000 rw-p 00000000 00:00 0
42602000-42603000 ---p 00000000 00:00 0
42603000-42e03000 rw-p 00000000 00:00 0
42e03000-42e04000 ---p 00000000 00:00 0
42e04000-43604000 rw-p 00000000 00:00 0
43604000-47065000 r--s 22280000 00:05 2835 /dev/shm37
47065000-4aac6000 r--s 22283000 00:05 2835 /dev/shm37
4aac6000-4e527000 r--s 22287000 00:05 2835 /dev/shm37
4e527000-51f88000 r--s 2228a000 00:05 2835 /dev/shm37
51f88000-559e9000 r--s 2228e000 00:05 2835 /dev/shm37
559e9000-5944a000 r--s 22292000 00:05 2835 /dev/shm37
5944a000-5ceab000 r--s 22295000 00:05 2835 /dev/shm37
5ceab000-6090c000 r--s 22299000 00:05 2835 /dev/shm37
6090c000-6436d000 r--s 2229d000 00:05 2835 /dev/shm37
6436d000-67dce000 r--s 222a0000 00:05 2835 /dev/shm37
67dce000-6b82f000 r--s 222a4000 00:05 2835 /dev/shm37
6b82f000-6f290000 r--s 222a8000 00:05 2835 /dev/shm37
6f290000-72cf1000 r--s 222ab000 00:05 2835 /dev/shm37
72cf1000-76752000 r--s 222af000 00:05 2835 /dev/shm37
76752000-7a1b3000 r--s 222b3000 00:05 2835 /dev/shm37
7a1b3000-7dc14000 r--s 222b6000 00:05 2835 /dev/shm37
7ff25000-7ff46000 rw-p 00000000 00:00 0 [stack]
00000000-00000000 r-xp 00000000 00:00 0 [vdso]

由于 mmap 继续因 ENOMEM 错误而失败,即使它有足够的位置来映射它,我决定对 mmap 进行分块。

for (i = 0; ((i < NB_CHUNK) && (ptr != MAP_FAILED)); i++) {
ptr = mmap(NULL,
ALIGN_ON_PAGE_SIZE((BIG_SIZE / NB_CHUNK)),
PROT_READ,
MAP_SHARED,
fd,
(off_t)ALIGN_ON_PAGE_SIZE((BIG_SIZE / NB_CHUNK) * i));
}

现在我没有更多的 ENOMEM 错误并且 mmap 运行良好,但是当我尝试读取其中的值时,我只读取了归零的内存。

问题是,我可以用这种方式对 mmap 进行分块吗?

最佳答案

也许您应该在运行进程时查看/proc/ /limits,找到“最大地址空间”行并查看其“软限制”列。 mmap 将导致地址空间有限的 ENOMEM。对于这种情况,您可以调用 setrlimit(2)在你的程序中修改进程的最大地址空间。

例如:

// set maximum size of the virtual address space to 1GiB
struct rlimit rlim;
rlim_t max_mem = 1 << 30;
rlim.rlim_cur = max_mem;
setrlimit(RLIMIT_AS, &rlim);

关于c - mmap 返回 ENOMEM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47304716/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com