我有64位REHL linux,Linux Linux ipms-sol1 2.6.32-71.el6.x86_64#1 SMP x86_64 x86_64 x86_64 GNU / Linux
RAM大小= ~38GB
我在/etc/sysctl.conf和amp;中更改了默认共享内存限制,如下所示:在内存中加载已更改的文件为sysctl -p
kernel.shmmni = 81474836
kernel.shmmax = 32212254720
kernel.shmall = 7864320
仅仅为了实验,我已经将shmmax大小更改为32GB,并尝试使用shmget()在代码中分配10GB,如下所示,但是单次拍摄无法获得10GB的共享内存,但是当我减少对共享空间的需求时8GB它是否能成功解决我可能出错的地方?
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#define SHMSZ 10737418240
main()
{
char c;
int shmspaceid;
key_t key;
char *shm, *s;
struct shmid_ds shmid;
key = 5678;
fprintf(stderr,"Changed code\n");
if ((shmspaceid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {
fprintf(stderr,"ERROR memory allocation failed\n");
return 1;
}
shmctl(shmspaceid, IPC_RMID, &shmid);
return 0;
}
此致 人士Himanshu
答案 0 :(得分:1)
我不确定此解决方案是否也适用于共享内存,但我从普通的malloc()调用中知道这种现象。
通常情况下,您在此处尝试时无法分配非常大的内存块。函数调用的含义是“为我分配10737418240字节的连续内存块”。通常,即使整个系统内存理论上可以满足这种需求,隐含的“连续内存块”也会强制可分配内存的限制要低得多。
内存中的程序结构,加载的程序数量都有助于阻止某些内存区域,并且不允许有10个连续的内存可分配内存。
我经常发现重启会改变它(当程序加载到堆上的不同位置时)。您可以使用以下内容尝试最大可分配块大小:
int i=1024;
int error=0;
while(!error) {
char *a=(char*)malloc(i);
error=(a==null);
if(!error)
printf("Successfully allocated %i.\n", i);
i*=2;
}
希望这有用或适用于此。我在检查为什么无法将最大系统内存分配给JVM时发现了这一点。
答案 1 :(得分:1)
在黑暗中拍摄:你没有足够的交换空间。默认情况下,共享内存需要在swap中保留空间。您可以使用SHM_NORESERVE
禁用此行为:
http://linux.die.net/man/2/shmget
SHM_NORESERVE(自Linux 2.6.15起)此标志用于相同的目的 作为mmap(2)MAP_NORESERVE标志。不要为此保留交换空间 分割。保留交换空间时,可以保证交换空间 可以修改细分。当交换空间没有保留时 如果没有可用的物理内存,可能会在写入时获得SIGSEGV。看到 还讨论了文件/ proc / sys / vm / overcommit_memory PROC(5)。
答案 2 :(得分:0)
我只是看着这个,我建议打印出问题的确切errno值和描述,而不是仅仅注意到它失败了。例如:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
//#define SHMSZ 10737418240
#define SHMSZ 8589934592
int main()
{
int shmspaceid;
key_t key = 5678;
struct shmid_ds shmid;
if ((shmspaceid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {
fprintf(stderr,"ERROR with shmget (%d: %s)\n", (int)(errno), strerror(errno));
return 1;
}
shmctl(shmspaceid, IPC_RMID, &shmid);
return 0;
}
我尝试用我的16 GB系统上的8 GB块和8 GB smhmax和shmall重现你的问题,但我不能。它工作正常。我建议使用ipcs -m
查找可能会阻止您的10 GB分配的其他共享块。并且一定要仔细查看shmget()
通过errno返回的确切错误代码。