Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 使用/dev/zero访问大内存(32 GB)_Linux_Memory_Mmap - Fatal编程技术网

Linux 使用/dev/zero访问大内存(32 GB)

Linux 使用/dev/zero访问大内存(32 GB),linux,memory,mmap,Linux,Memory,Mmap,我想使用/dev/zero来存储大量临时数据(32GB左右)。我正在这样做: fd = open("/dev/zero", O_RDWR ); // <Exit on error> vbase = (uint64_t*) mmap(NULL, MEMSIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, fd, 0); // <Exit on error> ftruncate(fd, (off_t) MEMSIZE

我想使用
/dev/zero
来存储大量临时数据(32GB左右)。我正在这样做:

fd = open("/dev/zero", O_RDWR );
// <Exit on error>
vbase = (uint64_t*) mmap(NULL, MEMSIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, fd, 0);
// <Exit on error>
ftruncate(fd, (off_t) MEMSIZE);
fd=open(“/dev/zero”,O_RDWR);
// 
vbase=(uint64_t*)mmap(NULL,MEMSIZE,PROT_READ | PROT_WRITE,MAP_PRIVATE | MAP_ANONYMOUS,fd,0);
// 
ftruncate(fd,(off_t)MEMSIZE);
我正在将
MEMSIZE
从1GB更改为32GB(执行memtest),看看我是否真的可以访问所有范围。1 GB的内存不足

我有什么遗漏吗?我说得对吗? 还是我遇到了一些系统限制?我如何检查是否发生了这种情况


注:我运行的许多程序在一个文件中生成了大量的数据,所以我不知道是否有人为的上限,只是我似乎遇到了一些问题。

我必须承认,我对你实际想做的事情感到困惑。无论如何,你所做的可能不起作用的几个原因:

  • 从mmap(2)手册页:“地图匿名
    映射没有任何文件支持;其内容初始化为零。fd和offset参数被忽略;”
  • 从空(4)手册页:“写入空或零特殊文件的数据将被丢弃。”

  • 所以无论如何,在MAP_ANONYMOUS之前,mmap'ing/dev/zero有时被用来获取匿名(即没有任何文件支持)内存。没有必要两者都做。在这两种情况下,实际写入所有这些内存意味着您需要某种类型的备份存储,物理内存或交换空间。如果您不能保证这一点,那么最好在有足够空间的文件系统上创建一个真正的文件。

    查看Linux内核
    mmap
    实现:

    vm_mmap vm_mmap_pgoff  do_mmap_pgoff  mmap_region  file->f_op->mmap(file, vma) 
    
  • 在函数
    do_mmap_pgoff
    中,它检查
    max_map_count

    if (mm->map_count > sysctl_max_map_count)
        return -ENOMEM;
    
  • 在函数
    mmap_region
    中,它检查进程虚拟地址限制(是否不受限制)

    在linux内核中,init任务默认设置为
    rlimit

    [RLIMIT_AS]                      = {  RLIM_INFINITY,  RLIM_INFINITY },     \
    
    #ifndef RLIM_INFINITY
    # define RLIM_INFINITY                (~0UL)
    #endif
    
    为了证明这一点,请使用
    test\u mem
    程序

    tmp> ./test_mem 
    RLIMIT_AS limit got sucessfully:
    soft_limit=4294967295, hard_limit=4294967295
    RLIMIT_DATA limit got sucessfully:
    soft_limit=4294967295, hard_limit=4294967295
    
    这意味着64位操作系统中32位应用程序的无限制意味着0xFFFFFFFF。更改shell虚拟地址限制,它可以正确反映

    root> ulimit -v 1024000
    tmp> ./test_mem 
    RLIMIT_AS limit got sucessfully:
    soft_limit=1048576000, hard_limit=1048576000
    RLIMIT_DATA limit got sucessfully:
    soft_limit=4294967295, hard_limit=4294967295
    
  • mmap_地区
    ,有一项责任检查

    accountable_mapping   security_vm_enough_memory_mm  cap_vm_enough_memory  __vm_enough_memory  overcommit/swap/admin and user reserve handling.
    

  • 请按照这三个步骤检查它们是否符合要求。

    您有64位系统吗?因为在32位系统中,您将无法映射32GB,甚至无法接近!更像你的1GB,我有。我在SLES 64位机器上运行
    tmp> ./test_mem 
    RLIMIT_AS limit got sucessfully:
    soft_limit=4294967295, hard_limit=4294967295
    RLIMIT_DATA limit got sucessfully:
    soft_limit=4294967295, hard_limit=4294967295
    
    struct rlimit rl;
    int ret;
    ret = getrlimit(RLIMIT_AS, &rl);
    if (ret == 0) {
        printf("RLIMIT_AS limit got sucessfully:\n");
        printf("soft_limit=%lld, hard_limit=%lld\n", (long long)rl.rlim_cur,          (long long)rl.rlim_max);
    }
    
    root> ulimit -v 1024000
    tmp> ./test_mem 
    RLIMIT_AS limit got sucessfully:
    soft_limit=1048576000, hard_limit=1048576000
    RLIMIT_DATA limit got sucessfully:
    soft_limit=4294967295, hard_limit=4294967295
    
    accountable_mapping   security_vm_enough_memory_mm  cap_vm_enough_memory  __vm_enough_memory  overcommit/swap/admin and user reserve handling.