Linux在x86_64上共享内存分配

时间:2011-10-17 12:34:09

标签: linux

我有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

3 个答案:

答案 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返回的确切错误代码。