c++ - 为什么创建大于内存的一维数组失败,但创建大于内存的二维数组没有问题?

标签 c++ arrays virtual-memory

为什么创建大于内存的一维数组失败,但可以创建大于内存的二维数组?我认为操作系统会为您提供虚拟内存,您可以根据需要请求任意数量的内存。直到您开始读取和写入内存并且它成为常驻集的一部分时,硬件限制才成为问题。

在内存为 512MB 的小型 VM 上我试过:

1, 512 MB array: no issue
1, 768 MB array: no issue
1, 879 MB array: no issue
1, 880 MB array: fails
1, 1024 MB array: fails
1000, 512MB arrays no issue (at this point
    I've allocated 256GB of virtual memory,
    well exceeding the physical limits)

在具有 8GB 内存的大型 VM 上,上述所有操作均有效。

对于这个实验,我使用了这段代码:

#include <stdio.h>      /* printf */
#include <stdlib.h>     /* atoi */
#include <iostream>
#include <unistd.h>

int main(int argc, char *argv[],char **envp) {
    if(argc < 3) {
        printf("main <mb> <times>\n");
        return -1;
    }

    int megabytes = atoi(argv[1]);
    int times = atoi(argv[1]);

    // megabytes    1024 kilobytes      1024 bytes          1 integer
    // --------   * ---------        *  ----------    *     --------
    //              megabyte            kilobyte            4 bytes
    int sizeOfArray = megabytes*1024*1024/sizeof(int);
    long long bytes = megabytes*1024*1024;
    printf("grabbing memory :%dmb, arrayEntrySize:%d, times:%d bytes:%lld\n",
                    megabytes, sizeOfArray, times, bytes);

    int ** array = new int*[times];
    for( int i = 0; i < times; i++) {
        array[i] = new int[sizeOfArray];
    }

    while(true) {
        // 1 second to microseconds
        usleep(1*1000000);
    }

    for( int i = 0; i < times; i++) {
        delete [] array[i];
    }
    delete [] array;
}

小型 512MB VM 实验的命令和输出:

free -h
              total        used        free      shared  buff/cache   available
Mem:           488M         66M         17M        5.6M        404M        381M
Swap:          511M         72K        511M

./a.out 512 1
grabbing memory :512mb, arrayEntrySize:134217728, times:512 bytes:536870912
./a.out 768 1
grabbing memory :768mb, arrayEntrySize:201326592, times:768 bytes:805306368

./a.out 1024 1
grabbing memory :1024mb, arrayEntrySize:268435456, times:1024 bytes:1073741824
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted (core dumped)

./a.out 512 1000
grabbing memory :512mb, arrayEntrySize:134217728, times:512 bytes:536870912
#htop
  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
 2768 root      20   0  256G  4912  2764 S  0.0  1.0  0:00.00 ./a.out 512 1000

在大型 8GB VM 上实验的命令和输出:

free -h
              total        used        free      shared      buff/cache   available
Mem:           7.8G         78M        7.6G        8.8M        159M        7.5G
Swap:          511M          0B        511M

./a.out 512 1
grabbing memory :512mb, arrayEntrySize:134217728, times:512 bytes:536870912
./a.out 768 1
grabbing memory :768mb, arrayEntrySize:201326592, times:768 bytes:805306368
./a.out 1024 1
grabbing memory :1024mb, arrayEntrySize:268435456, times:1024 bytes:1073741824
./a.out 512 1000 
grabbing memory :512mb, arrayEntrySize:134217728, times:512 bytes:536870912
# htop
  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
 1292 root      20   0  256G  6920  2720 S  0.0  0.1  0:00.00 ./a.out 512 1000

最佳答案

这是因为内存是根据您的请求量分配到 block 中的。

您要求二维数组中的一系列相对较小的 block ,每个 block 不一定彼此相邻。

然而,一维数组非常庞大,需要一个全尺寸且连续的内存块,即使您有很多可用内存,您也可能没有那个大小的 block 可用。

关于c++ - 为什么创建大于内存的一维数组失败,但创建大于内存的二维数组没有问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51561992/

相关文章:

ruby - Ruby 中的数组对象无法初始化为数组

linux - linux下如何控制虚拟内存管理?

c++ - 获取 QSqlError ("", "", "") 但数据已插入

c++ - 声明没有指针的默认参数循环引用?

c - 数组的地址与数组[0]的地址 - C语言

php:检查数组是否有重复项

c++ - 错误 LNK2019 :unresolved external symbol

c++ - 合并功能以获得更清晰的代码?

ios - `NSUserDefaults synchronize`怎么跑得这么快?

linux-kernel - RISC-V 中的地址指定