共享内存:shmget失败:设备上没有剩余空间 – 如何增加限制?

我在程序中多次调用shmget,得到平均大小为85840字节的shm。 我获得大约32771 shm ok,然后shmget不返回一个SHM,但错误:“没有空间留在设备上”。

我已经将内核限制增加到:

$ sysctl -A|grep shm kernel.shmmax = 33554432 kernel.shmall = 1677721600 kernel.shmmni = 409600 

但仍然有问题。 为什么?

我还必须把东西放入/etc/security/limits.conf吗? 我只有“用户nofile 1000000”,因为该程序也打开尽可能多的文件作为shms。

这是免费的输出

 $ free total used free shared buffers cached Mem: 8150236 7261676 888560 0 488100 3270792 -/+ buffers/cache: 3502784 4647452 Swap: 12287992 554692 11733300 

和ipcs

 $ ipcs -lm ------ Shared Memory Limits -------- max number of segments = 409600 max seg size (kbytes) = 1638400 max total shared memory (kbytes) = 6710886400 min seg size (bytes) = 1 

由于我认为shm能够被换出,所以应该有足够的空间。

原来shmmni在内核中被限制为32768:

 #define IPCMNI 32768 /* <= MAX_INT limit for ipc arrays (including sysctl changes) */ 

在文件...version.../include/linux/ipc.h

这么短的内核重新编译,就是共享内存段数量的硬性限制。

使用ipcs -l检查实际有效的限制,使用ipcs -aipcs -m查看正在使用的内容,以便比较输出。 查看nattch列:是否有没有进程附加的进程退出时(通常意味着程序崩溃)没有被删除的段? ipcrm可以清除它们,但如果这是一个testing机器,重启会更快(并且确保你的更改被限制)。

你的内核参数似乎很奇怪。 特别是, shmall是页数而不是字节数,4kB是默认页面大小(运行getconf PAGESIZE来检查你正在使用的是什么)。 你有多less兆字节的RAM?

现在,你说你得到大约32771共享内存段,这也是大约32768(或2到15),这表明一个有符号的16位int是限制因素。 你在运行什么内核(因为这会有自己的限制)? 这两者可能有关系。

由于shmget()分配一个新的共享内存段,而且你似乎使用了很多(考虑你的limits.conf),不可能使用太多的共享内存段吗? 我没有很多调用shmget()的经验,但在我看来,可能的打开文件(1000000)的数量大于允许的共享内存段(SHMMNI)的数量(409600)。