strike1217 さんの一連の質問から OS は Linux、CPU アーキテクチャは x86_64 が前提でよいでしょうか。
4 * 3 * 100000000 = 1.2Gbの領域が必要になるはずです。
この場合、「OSは1.2Gbすべての配列を一度にメモリ上に展開させる」ということでしょうか??
「メモリ上に展開する」の意味が微妙ですが、初期値なしのデータセグメント(.bss)ですので、ゼロが連続する擬似ファイルにマッピングされます。これは /dev/zero をマッピングしたのと同義です。つまり、予約はされます(この詳細がまた難しいけど)が、その実体がすぐに用意されるわけではありません。
まずは、メモリマッピングの概念について勉強して頂く必要があります。OSが管理するメモリはページングによって、すべてなんらかのディスク上のデータとマッピングされる(=対応付けられる)と考えてください。それは、スワップかもしれませんし、実行可能ファイルのテキストセグメントかもしれませんし、/dev/zero のようなデバイスかもしれません。
/dev/zero は永遠にゼロが続くデバイスですので、どこを読み出してもゼロの連続しか出てきません。
今、この変数tの先頭アドレスが /dev/zero のオフセット0にマッピングされたとします。配列の100000000個めの要素にアクセスすると、対応する物理メモリページが割り当てられていないので、割り込みが発生し、カーネルによってページインが実行されます。そして、 /dev/zero のオフセット 1.2Gb の1ページが読み込まれますが、このデバイスは擬似デバイスなので、単に0の連続を1ページ分返すだけです。
この動作が終わった段階で物理メモリの消費は1ページです。ちなみにこのページに書き込むと /dev/zero に対するマッピングは解除されて、新しいメモリにコピーされ、そのメモリは swap 上の新しい1ページに対応付けられます(ここも詳細はもう少し難しい)。これを copy on write といいます。
10億個の配列を使用した場合、12x10^9になるので、メモリは12GB搭載していないと動かない・・・ということでしょうか?
上記の通りですので、メモリは12GB搭載してなくても動きます。しかし、 swap は 12GB 割り当ててないと動きません(これも厳密にはオーバコミットがあるので、ちょっと違う)。
注意)データセグメント、テキストセグメントはリンカ、ローダの用語であり、いわゆるメモリのセグメンテーションとは無関係です。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/09/26 12:41
2016/09/26 12:57 編集