我试图在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),程序应该抛出错误。我看到了本主题中提到的一些问题,但我无法从那里给出的答案中解决我的问题。
答案 0 :(得分:2)
Linux overcommits,这意味着它可以允许进程拥有比系统上可用内存更多的内存,但直到该进程实际使用该内存才会分配实际内存(磁盘上的物理主内存或交换空间)为了这个过程。我的猜测是Mac OS X以类似的方式工作。
答案 1 :(得分:2)
在某些系统上,您可以分配适合地址空间的任意数量的内存。当您开始实际使用该内存时问题就开始了。
操作系统保留了进程的虚拟地址范围,而不是将其映射到任何物理地址,甚至检查是否有足够的物理内存(包括交换)来支持该地址范围。当进程尝试访问新分配的页面时,映射仅以逐页方式发生。这称为内存过量使用。
尝试访问大型阵列的每个sysconf(_SC_PAGESIZE)
字节,看看会发生什么。