mmap返回ENOMEM [英] mmap returning ENOMEM

查看:106
本文介绍了mmap返回ENOMEM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I read every post linked to this topic and didn't find anything that was able to solve my problem.

我正在尝试映射由基础文件支持的900Mb MAP_SHARED. 我们有2Gb的RAM和只有2Gb的虚拟内存(为内核保留1Gb,为管理程序保留1Gb).

I'm trying to map a 900Mb MAP_SHARED backed by an underlying file. We have 2Gb of RAM and only 2Gb of VIRTUAL MEMORY available (1Gb reserved for Kernel + 1Gb reserved for Hypervisor).

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

我当时正在考虑缺少可用的VMEM,所以我尝试放入"sysctl -w vm.overcommit_memory = 1",但是它也因此失败了.

I was thinking about a lack of VMEM available so I tried to put "sysctl -w vm.overcommit_memory=1" but it failed with this too.

我在下面进行了一个小循环,以了解mmap真正在哪种尺寸上失败了,我发现它的大小接近700Mb,因此它可以正常工作到700Mb,然后失败了.

I made a little loop (below) to know at which size mmap is really failing and I found it was next to 700Mb, so it works fine up to 700Mb and then failed.

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的大小相同.

PS: shm_open and ftruncate are not returning any error. ftruncate and mmap are working with the same size.

free -m返回交换0 0 0.

free -m is returning Swap 0 0 0.

显然出现了这样的情况,我在VMEM中没有900Mb的连续空间,就像我说的那样,只有很小的mmap,一个台阶一个台阶,我能够达到〜720Mo的mmap,但是我没有找到关于此连续限制的解决方法.我是否必须将其拆分为几个文件描述符或类似的文件?

EDIT 1: Obviously it cames up that I've no 900Mb contiguous space in VMEM, like I said with little mmap, stair by stair, I'm able to reach a mmap of ~720Mo but I didn't find a workaround about this contiguous limitation. Do I have to split it on several file descriptor or something like that ?

通过改善shmem大小,我现在可以进行mmap(870Mb)了,几乎可以:D 但是我不明白为什么堆和第一个库之间会有 巨大的GAP缺口〜880Mb ,有人对我有提示吗?

With some shmem size improvement I'm now able to mmap(870Mb), almost there :D But I don't understand why there is a HUGE GAP of ~880Mb between the heap and the first library, does someone have an hint for me?

在proc/$ PID/maps结果下面

Below the result of 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]


现在,我已经将所有小的共享内存移到了堆之后(请参见下文),并将> 900Mb移到了lib上方(以便为我的大型共享内存提供最大的可用空间)


EDIT 3: Now I've moved all little shared memories (see below) just after the heap and let the >900Mb one above the lib (in order to have the maximum available space for my big shared mem)

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进行分块.

As mmap continued to fail with ENOMEM error even if it got enough place to map it I decided to chunk the 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运行良好,但是当我尝试读取其中的一个值时,我只读取了零内存.

Now I've no more ENOMEM error and the mmap is doing well but when I try to read a value in it I'm only reading zeroed memory.

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

The question is, Can I chunk a mmap this way ?

推荐答案

也许您应该在运行进程时查看/proc/< pid>/limits,找到最大地址空间"行,并查看其软限制"柱子. mmap将导致ENOMEM的地址空间有限.对于这种情况,您可以在程序中调用 setrlimit(2)来修改最大地址处理空间.

例如:

Maybe you should look at /proc/<pid>/limits while running your process, find "Max address space" row and see its "Soft Limit" column. mmap will cause ENOMEM for limited address space. For this situation, you can call setrlimit(2) in your program to modify Max address space of process.

For example:

// 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);

这篇关于mmap返回ENOMEM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆