【发布时间】:2021-09-22 17:21:49
【问题描述】:
我刚刚了解了堆和堆栈内存分配,并且很好奇我可以在堆上分配多少。正如我所见,堆分配提供了指向内存的指针,其中请求的连续字节数是空闲的。所以我编写了以下代码来对我可以分配的最大数量进行二进制搜索。
#include <iostream>
#include <chrono>
#include <cassert>
using namespace std;
int main ( void ) {
size_t lo = 0, hi = -1ll; hi >>= 1; // i am doing this to avoid overflow.
while (lo + 1 != hi) {
char * ptr = NULL;
ptr = (char*) malloc((lo+hi)>>1);
if (ptr != NULL) lo = (lo+hi)>>1;
else hi = (lo+hi)>>1;
free(ptr);
}
cout << lo << " is amount of bytes of memory that we could allocate on this system's heap.\n";
cout << (lo>>10) << " KB\n";
cout << (lo>>20) << " MB\n";
cout << (lo>>30) << " GB\n";
// additional code.
// this part is to read and write at n uniformly distant cells in 20GB of memory.
auto start = chrono::high_resolution_clock::now();
int * arr = (int *) malloc(5ll<<32); // 20GB
bool ok = true;
const int n = 10; // n means 5 * 2 ^ n cells to write and read.
for (long long i=0; i<(5<<n); ++i) {
assert((5ll<<30) > (i<<(30-n)));
arr[i << (30-n)] = 23;
ok &= arr[i << (30-n)] == 23;
}
auto end = chrono::high_resolution_clock::now();
long long elapsed = chrono::duration_cast<chrono::milliseconds>(end - start).count();
cout << "Elapsed time : " << elapsed << "ms\n";
cout << (ok ? "ok is True\n" : "ok is False\n");
free(arr);
return 0;
}
输出
27672117247 is amount of bytes of memory that we could allocate on this system's heap.
27023551 KB
26390 MB
25 GB
Elapsed time : 13ms
ok is True
我知道在同一台机器上输出会随着时间而变化。但我没想到它总是在 ~22GB 左右,因为我的系统 RAM 的容量只有 8GB。这是怎么回事?
【问题讨论】:
-
我假设这是 linux?一台 Windows 机器可能会达到 16GB 左右
-
它在使用 mingw 的 windows 上。感谢您提供相关文本。我会读一读。
-
您还会看到有趣的东西,例如声明一个巨大的数组,并且几乎看不到内存消耗的指针移动,因为您没有使用太多该数组。如果您写入数组的开头和结尾,您可能会发现您只在开头给出一个页面,在结尾给出一个页面,并且在这些页面之间绝对没有实际分配给数组的内存。
-
@user4581301 请详细说明第一页和最后一页之间绝对没有记忆。那是什么意思?。我尝试在距离均匀的 n 个单元上写入和读取存储单元。 1k 个单元在 15 毫秒内运行(2^15)在 250 毫秒内运行并且(2^20)挂起我的系统。我确实理解页面的概念,就像在需要时在 RAM 中调用它们一样,但为什么它会挂在 2^20 个单元调用上。我更新了代码以向您展示新添加的内容。