为什么当行>列时数组的内存占用量更大
why is the memory footprint of array larger when row > column
int **arr_a;//4x268435456
arr_a = new int*[4];
for (int i = 0; i < 4; i++) {
arr_a[i] = new int[268435456];
for (int j = 0; j < 268435456; j++) {
arr_a[i][j] = j;
}
}
int **arr_b;//268435456x4
arr_b = new int*[268435456];
for (int i = 0; i < 268435456; i++) {
arr_b[i] = new int[4];
for (int j = 0; j < 4; j++) {
arr_b[i][j] = j;
}
}
理论上:
arr_a:
sizeof(int**) + 4 * sizeof(int**) + 4 * 268435456 * sizeof(int)
=4G
arr_b :
sizeof(int**) + 268435456 * sizeof(int*) + 268435456 * 4 * sizeof(int)
=6G
但实际上:
arr_a = 4G
arr_b = 10.6g ???为什么....
环境:Win10 64bit 32g RAM VS2017
我的结果
您看到小对象的分配开销结果。除了阵列本身中的四个整数外,new int[4]
还在这两个方面造成开销:
- 最小分配大小 - 分配器返回的数据块具有最小尺寸,通常至少32个字节,您仅使用16个字节
-
簿记 - 除了为您提供内存外,分配器存储了一小部分数据,以帮助您在调用
delete[]
时做正确的事情。
这两个开销将您需要的内存量乘以:
- 64位系统上的
268435456 * sizeof(int*)
是2G - 假设32字节分配,
268435456 * 32
是另一个8G
当您处理大型对象(例如arr_a
的元素(时,与分配大小相比,开销非常小,您可以安全地忽略它:只有五个分配,我们正在谈论几百个字节4G总分配。当对象很小时,额外的分配与"有效载荷"的大小相当,甚至可能在某些极端情况下超过它。
每个堆分配都带有开销,因此Heap Manager可以跟踪您要求的块。您还需要将其分解为算术。这不像您要求的块的大小那样简单。
这里有一个很好的概述(尽管Windows 8(。
相关文章:
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 使用无符号字符数组有效存储内存
- 在将数字随机生成为数组期间从内存输出随机数的数组
- 为什么调用堆栈数组会导致内存泄漏
- 在c++中为我自己的基于指针的数组分配内存的正确方法
- 在 C++ 中访问数组负索引处的内存不会返回垃圾
- 查找自动生成键并具有线性内存消耗的小型关联数组
- C++,为什么数组比矢量更快,使用更少的内存
- 介于 [固定数组] 和 [带内存分配的指针] 之间的性能
- 当另一个数组是内存集时,内存集是否会更改数组长度?
- 动态分配字符数组的内存
- 将内存分配返回值强制转换为 TYPE 数组
- 销毁C++中动态分配的内存(数组对象)
- 给定特定内存地址的数组的动态内存分配
- 如何通过 malloc 为队列数组分配内存?
- 如何使用内存集清除字符数组
- 如何初始化所有元素为 0 的指针的二维动态内存数组
- 共享内存数组是否由 CreateFileMapping/MapViewOfFile 零初始化
- C++ 分配 struc 的内存数组
- 在CUDA中有效初始化共享内存数组