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 はオーバーコミットします。つまり、システムで利用可能なメモリよりも多くのメモリをプロセスに許可できますが、実際のメモリ (物理メイン メモリまたはディスク上のスワップ領域) がプロセスに割り当てられるのは、そのメモリがプロセスによって実際に使用されるまでではありません。 . 私の推測では、Mac OS X も同様の方法で動作します。

于 2012-09-13T17:59:45.627 に答える
2

一部のシステムでは、アドレス空間に収まる任意の量のメモリを割り当てることができます。問題は、そのメモリを実際に使用し始めたときに始まります。

何が起こるかというと、OS はプロセスの仮想アドレス範囲を予約しますが、それを物理的なものにマッピングしたり、そのアドレス範囲をバックアップするのに十分な物理メモリ (スワップを含む) があることを確認したりすることさえありません。マッピングは、プロセスが新しく割り当てられたページにアクセスしようとしたときに、ページごとにのみ発生します。これは、メモリーのオーバーコミットと呼ばれます。

sysconf(_SC_PAGESIZE)巨大な配列の 1 バイトごとにアクセスしてみて、何が起こるかを確認してください。

于 2012-09-13T18:14:24.553 に答える