mmap 返回带有 shm_open 文件对象的 ENOMEM

发布于 2024-12-27 17:15:29 字数 1996 浏览 5 评论 0原文

我正在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

慕巷 2025-01-03 17:15:29

我误读了 mmap 的文档,它说 mmap 返回基于第一个参数的映射(在我的例子中是先前映射的地址),结果由实现定义。我将此视为 mmap 可能会为我重新映射我之前的映射的建议,但事实并非如此。如果我使用了 MAP_FIXED 标志,则可能只会出现这种情况,但我避免了这种情况,因为文档建议不要这样做。

无论如何,在创建新映射之前,有必要使用 munmap 删除以前的映射。

I misread the documentation for mmap, which says that mmap 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 that mmap 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 the MAP_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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文