分配大量内存时 mmap() 失败

mmap() fails when allocating large amounts of memory

对于我的程序,我需要一个字节数组,大小为进程虚拟内存的 1/8 space。

我使用 getrlimit() 系统调用获取虚拟内存大小,然后使用 setrlimit()[=31= 将其设置为最大限制].然后我使用 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() 指定偏移量,使用软限制而不是硬限制,在标志中使用 MAP_NORESERVE 分配 1/32 而不是 1/8 的内存 - 到目前为止没有任何效果。 我尝试了 运行 一个简单的测试程序,它只执行 mmap() 而没有其他内存分配,它也不起作用。

这是我得到的:

memory size is 18446744073709551615 bytes, array size is 2305843009213693951 bytes mmap failed with 12. allocation size = 2305843009213693951

getrlimit 的联机帮助页有以下解释。

RLIMIT_AS
  This is the maximum size of the process's virtual memory (address space).

它不是return可用内存大小,而是64位地址中的内存大小(18EB)space。

如果需要了解可用内存大小,可以使用sysinfo函数。

#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <linux/kernel.h>
#include <sys/sysinfo.h>

int main()
{
    struct rlimit m;
    struct sysinfo s;
    getrlimit(RLIMIT_AS, &m);
    printf("getrlimit rlim_cur:%ld, rlim_max:%ld\n", m.rlim_cur, m.rlim_max);
    sysinfo(&s);
    printf("sysinfo totalram:%ld, freeram:%ld, totalswap:%ld, freeswap:%ld\n", s.totalram, s.freeram, s.totalswap, s.freeswap);
    return 0;
}