我在程序中多次调用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 -a和ipcs -m查看正在使用的内容,以便比较输出。 查看nattch列:是否有没有进程附加的进程退出时(通常意味着程序崩溃)没有被删除的段? ipcrm可以清除它们,但如果这是一个testing机器,重启会更快(并且确保你的更改被限制)。
你的内核参数似乎很奇怪。 特别是, shmall是页数而不是字节数,4kB是默认页面大小(运行getconf PAGESIZE来检查你正在使用的是什么)。 你有多less兆字节的RAM?
现在,你说你得到大约32771共享内存段,这也是大约32768(或2到15),这表明一个有符号的16位int是限制因素。 你在运行什么内核(因为这会有自己的限制)? 这两者可能有关系。
由于shmget()分配一个新的共享内存段,而且你似乎使用了很多(考虑你的limits.conf),不可能使用太多的共享内存段吗? 我没有很多调用shmget()的经验,但在我看来,可能的打开文件(1000000)的数量大于允许的共享内存段(SHMMNI)的数量(409600)。