1

我正在尝试在 C++ 中找到可以在堆栈、全局和堆内存上分配的最大内存。我在具有 32 GB 内存的 Linux 系统和具有 2 GB RAM 的 Mac 上尝试这个程序。

/* test to determine the maximum memory that could be allocated for static, heap and stack memory  */

#include <iostream>
using namespace std;

//static/global
long double a[200000000];

int main()
{
//stack
long double b[999999999];

//heap
long double *c = new long double[3999999999];
cout << "Sizeof(long double) = " << sizeof(long double) << " bytes\n";
cout << "Allocated Global (Static) size of a = " << (double)((sizeof(a))/(double)(1024*1024*1024)) << " Gbytes \n";
cout << "Allocated Stack size of b = " << (double)((sizeof(b))/(double)(1024*1024*1024)) << " Gbytes \n";
cout << "Allocated Heap Size of c = " << (double)((3999999999 * sizeof(long double))/(double)(1024*1024*1024)) << " Gbytes \n";

delete[] c;

return 0;

}

结果(两者):

Sizeof(long double) = 16 bytes
Allocated Global (Static) size of a = 2.98023 Gbytes 
Allocated Stack size of b = 14.9012 Gbytes 
Allocated Heap Size of c = 59.6046 Gbytes

我正在使用 GCC 4.2.1。我的问题是:

为什么我的程序正在运行?我预计由于堆栈耗尽(Linux 中为 16 MB,Mac 中为 8 MB),程序应该会抛出一个错误。我看到了这个主题中提出的许多问题中的一些,但我无法从那里给出的答案中解决我的问题。

4

2 回答 2

2

Linux overcommits,这意味着它可以允许进程比系统上可用的内存更多,但直到该内存被进程实际使用时,才会为进程分配实际内存(物理主内存或磁盘上的交换空间) . 我的猜测是 Mac OS X 以类似的方式工作。

于 2012-09-13T17:59:45.627 回答
2

在某些系统上,您可以分配适合地址空间的任意数量的内存。当您开始实际使用该内存时,问题就开始了。

发生的情况是操作系统为进程保留了一个虚拟地址范围,没有将其映射到任何物理地址,甚至没有检查是否有足够的物理内存(包括交换)来支持该地址范围。当进程尝试访问新分配的页面时,映射仅以逐页方式发生。这称为内存过度使用

尝试访问sysconf(_SC_PAGESIZE)巨大数组的每个字节,看看会发生什么。

于 2012-09-13T18:14:24.553 回答