mmap 返回带有 shm_open 文件对象的 ENOMEM
我正在 Linux 中试验 shm_open
,但遇到了问题。我经常使用 ftrunc
调整共享内存段的大小,并使用 mmap
重新映射调整大小的段。然而,在 20 MB 左右,我从 mmap
获得了 ENOMEM
。
我已尝试执行以下操作来解决该问题:
首先,我发现了这些 sysctl 参数。我重新配置了它们:(
kernel.shmmax = 268435456
kernel.shmall = 2097152
shmall
是在页面中指定的)
此后问题仍然出现。调查导致问题的调整大小的详细信息显示,对 ftrunc
进行的调用以调整共享内存对象的大小成功(/dev/shm
中的相应文件具有所请求的新尺寸)。
此处的文档提出了 ENOMEM< 的三种可能原因/code>
errno
:
[ENOMEM]
指定了 MAP_FIXED,并且范围 [addr,addr+len) 超出了进程的地址空间所允许的范围;或者,如果未指定 MAP_FIXED 并且地址空间中没有足够的空间来实现映射。
[ENOMEM]
[ML] 如果 mlockall() 需要,则映射无法锁定在内存中,因为它需要的空间超出了系统能够提供的空间。
[ENOMEM]
[TYM] fildes 指定的类型化内存对象中没有足够的未分配内存资源来分配 len 字节。
我没有使用 MAP_FIXED 或锁定,并且 /dev/shm 中图像的大小表明第三个原因不是问题。我的 mmap
调用如下所示:
mmap(mem, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)
其中 mem
最初为 0,此后引用最后一个成功映射的地址 mmap
。
我发现信息表明 ulimit
设置可能会将可映射的内存限制为单个进程,但我认为问题不在这里。以防万一,ulimit -a
在我的机器上看起来像这样:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 20
file size (blocks, -f) unlimited
pending signals (-i) 16382
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 65536
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) unlimited
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
I'm experimenting with shm_open
in Linux and I'm running into problems. I'm frequently resizing a shared memory segment with ftrunc
and using mmap
to remap the resized segment. However, right around the 20 megabyte mark I get ENOMEM
from mmap
.
I have attempted the following to do to resolve the issue:
First, I found out about these sysctl
parameters. I reconfigured them:
kernel.shmmax = 268435456
kernel.shmall = 2097152
(shmall
is specified in pages)
The issue still occurred after this. Investigating the details of the resize that causes the issue revealed that the call made to ftrunc
to resize the shared memory object succeeded (the corresponding file in /dev/shm
had the requested new size).
Documentation from here suggests three possible causes for an ENOMEM
errno
:
[ENOMEM]
MAP_FIXED was specified, and the range [addr,addr+len) exceeds that allowed for the address space of a process; or, if MAP_FIXED was not specified and there is insufficient room in the address space to effect the mapping.
[ENOMEM]
[ML] The mapping could not be locked in memory, if required by mlockall(), because it would require more space than the system is able to supply.
[ENOMEM]
[TYM] Not enough unallocated memory resources remain in the typed memory object designated by fildes to allocate len bytes.
I am not using MAP_FIXED
or locking, and the size of the image in /dev/shm
suggests that the third reason is not the problem. My mmap
call looks like this:
mmap(mem, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)
where mem
initially is 0 and thereafter refers to the last address mmap
successfully mapped.
I found information suggesting that ulimit
settings could be limiting the memory mappable into a single process, but I don't think the problem was here. Just in case, ulimit -a
looks like this on my machine:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 20
file size (blocks, -f) unlimited
pending signals (-i) 16382
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 65536
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) unlimited
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我误读了
mmap
的文档,它说mmap
返回基于第一个参数的映射(在我的例子中是先前映射的地址),结果由实现定义。我将此视为mmap
可能会为我重新映射我之前的映射的建议,但事实并非如此。如果我使用了 MAP_FIXED 标志,则可能只会出现这种情况,但我避免了这种情况,因为文档建议不要这样做。无论如何,在创建新映射之前,有必要使用
munmap
删除以前的映射。I misread the documentation for
mmap
, which says thatmmap
returns a mapping based on the first parameter (the previously mapped address in my case), and the result is defined by implementation. I took this as a suggestion thatmmap
might remap my previous mapping for me, but this was certainly not the case. this might only have been the case if I had used theMAP_FIXED
flag, but I avoided this because the documentation recommended against it.In any case, it was necessary to use
munmap
to remove the previous mapping before creating a new one.