C++ 中堆栈、静态和堆内存的最大内存
Posted
技术标签:
【中文标题】C++ 中堆栈、静态和堆内存的最大内存【英文标题】:Maximum memory for stack, static and heap memory in C++ 【发布时间】:2012-09-06 21:03:54 【问题描述】:我正在尝试在 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),程序应该会抛出一个错误。我看到了这个主题中提出的许多问题中的一些,但我无法从那里给出的答案中解决我的问题。
【问题讨论】:
你从哪里得到这些 16MB/8MB 的数据?这些看起来像默认线程堆栈大小,而不是最大进程堆栈大小。 我知道有些操作系统可以扩展堆栈直到它耗尽虚拟内存,也许你们两个都可以?或者也许编译器将你认为在堆栈中的东西移动到了全局? (递归函数会阻止这种优化)ulimit -a
在 Mac 上给出 stack size (kbytes, -s) 8192
,在 Linux 上给出 stack size (kbytes, -s) 10240
。抱歉,我想是 10 MB(不是 16),我会编辑。
不,其他人正在使用这台机器,所以它确实是 16 MB。谢谢。
【参考方案1】:
Linux 过度使用,这意味着它可以允许进程比系统上可用的内存更多,但直到该内存被进程实际使用时才会分配实际内存(物理主内存或磁盘上的交换空间)为过程。我的猜测是 Mac OS X 以类似的方式工作。
【讨论】:
【参考方案2】:在某些系统上,您可以分配适合地址空间的任意数量的内存。当您开始实际使用该内存时,问题就开始了。
操作系统会为进程保留一个虚拟地址范围,而不会将其映射到任何物理地址,甚至检查是否有足够的物理内存(包括交换)来支持该地址范围。当进程尝试访问新分配的页面时,映射仅以逐页方式发生。这称为内存过度使用。
尝试访问大型数组的每个 sysconf(_SC_PAGESIZE)
th 字节,看看会发生什么。
【讨论】:
我认为这只是堆分配的情况,而不是堆栈。 @Sayan:您的操作系统可能不知道内存分配是用于堆栈还是堆使用。以上是关于C++ 中堆栈、静态和堆内存的最大内存的主要内容,如果未能解决你的问题,请参考以下文章