【发布时间】:2020-11-29 10:28:46
【问题描述】:
对于我的程序,我需要一个大小为进程虚拟内存空间 1/8 的字节数组。
我使用 getrlimit() 系统调用来获取虚拟内存大小,然后使用 setrlimit() 将其设置为最大限制。然后我使用 mmap() 分配一个大小为虚拟内存大小 1/8 的数组。像这样:
struct rlimit mem_limit;
if(getrlimit(RLIMIT_AS, &mem_limit) != 0){
return -errno;
}
mem_limit.rlim_cur = mem_limit.rlim_max;
if(setrlimit(RLIMIT_AS, &mem_limit) != 0){
return -errno;
}
array_size = (mem_limit.rlim_cur)/8;
printf("memory size is %lu bytes, array size is %lu bytes\n", mem_limit.rlim_cur, array_size);
mem_array = (char*) mmap(0, array_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if(mem_array == MAP_FAILED){
printf("mmap failed with %d. allocation size = %lu\n", errno, g_shadow_mem_size);
return -errno;
}
mmap() 在此处失败并显示 errno 12,据我所知,这意味着内存不足。我不明白为什么,因为程序除了这个之外几乎没有分配内存,更不用说另外 7/8 的内存了。
我尝试使用 malloc(),为 mmap() 指定偏移量,使用软限制而不是硬限制,而是分配 1/32 的内存1/8,在标志中使用 MAP_NORESERVE - 到目前为止没有任何效果。 我尝试运行一个简单的测试程序,它只执行 mmap() 而没有其他内存分配,它也不起作用。
这是我得到的:
内存大小为18446744073709551615字节,数组大小为2305843009213693951字节 mmap 以 12 失败。分配大小 = 2305843009213693951
【问题讨论】:
-
对于“数组”,您需要连续的内存,或者更确切地说,您需要在虚拟内存中连续映射的数组的内存。而且系统已经有相当多的页面映射到您的进程,这意味着不可能连续映射那么多页面。
-
@Someprogrammerdude 您应该将其发布为答案
-
在主函数中添加对 pause() 的调用并查看 /proc/[pid]/smaps。您将看到分配了几个虚拟内存空间区域但不是连续的。您在分配的内存区域之间有很多漏洞。 mmap() 只能在这些漏洞中分配内存。
标签: c memory-management mmap virtual-memory