2

このコードを見てください:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char* foo = (char*)malloc(500000000);

    // when I uncomment stuff that's below then operating system
    // admits that this program uses 500MB of memory. If I keep
    // this commented, it claims that the program uses almost no
    // memory at all. Why is it so?

    /*
    for (int i=0; i<500000000; i++)
    {
        foo[i] = (char)i;
    }
    */

    int bar; scanf("%d", &bar); // wait so I can see what's goin on

    free(foo);

    return 0;
}

私の直感は単純です。malloc呼び出しで500MBを割り当てると、OSはプロセスが500MBを超えるメモリを使用していると言うはずです。しかし、どうやら、それはそのようには機能しません。私は何が欠けていますか?OSはどのようなトリックを使用していますか、何について読む必要がありますか?

手がかりを事前にありがとう。

4

5 に答える 5

7

私は何が欠けていますか?OSが使用しているトリックは何ですか、私は何について読むべきですか

これは怠惰な割り当ての一形態です。一言で言えば:

  • mallocOSに大量のメモリを要求すると、OSは「確かに、ここに行きます」と言って、(ほとんど)何もしません。
  • OSは、「割り当てられた」ページに決して触れないことを密かに望んでいます。
  • 割り当てられたページに触れると、OSは避けられないページフォールトをキャッチし、ため息をついてページを割り当てます。

これはページごとに発生します。したがって、システムのページサイズ(おそらく4096など)forだけインクリメントしても同じ使用法が得られます。簡単なトリックとして、タッチiする要素の数で遊んでみてください。forボーナスとして、サイズをページのサイズで割ってメモリ使用量を予測してみてください

于 2013-01-06T21:06:30.970 に答える
2

プロセス内のすべてのメモリ使用量は、OSによって仮想化されます。コード内でメモリブロックを「割り当て」ている可能性がありますが、コードで実際に使用されるまで、OSは実際にはそれを物理メモリにコミットしていない可能性があります。

于 2013-01-06T21:05:56.687 に答える
1

OSは、使用するまでメモリを割り当てていない(または割り当てていることを示していない)可能性があります。

いずれにせよ、malloc()このような大きなチャンクを割り当てる場合は、の戻り値を確認することをお勧めします。失敗するmalloc() 可能性があります。

于 2013-01-06T21:05:32.797 に答える
1

オペレーティングシステムのメモリページは、アクセスしたときにのみ実際にプロセスに割り当てられます(この場合は書き込みによって)。正確な動作は、コンパイラとOSによって異なります。別のシステムでは、メモリがすぐに使い果たされる場合があります。

于 2013-01-06T21:07:15.063 に答える
-1

OSとは何の関係もありません。コンパイラは、割り当てられたメモリが使用されていない場合に、結果のバイナリにメモリを割り当てるステートメントを削除するように、結果のコードを最適化します。これは、コンパイラの最適化レベルをゼロに設定することで確認できます。次に、メモリが毎回割り当てられるため、どちらの場合も500MBを取得します。

于 2013-01-06T23:42:20.087 に答える