1

Linux では、calloc は malloc + memset とまったく同じですか、それとも正確な Linux/カーネル バージョンに依存しますか?

物理的に持っているよりも多くの RAM を呼び出すことができるかどうかという質問に特に興味があります (物理的に持っているよりも多くの RAM を確実に malloc できるため、書き込むことはできません)。つまり、 calloc は、仕様が示唆するように、割り当てられたメモリに常に実際に書き込みますか。

4

4 に答える 4

5

もちろん、それは実装に依存しますが、最近の Linux ではおそらく可能です。やってみるのが一番簡単なのですが、以下の論理で言っています。

mallocカーネルは、実際に使用するまでメモリの割り当てを遅らせるため、持っているメモリ (物理 + 仮想) を超えることができます。これは、メモリの制限によりプログラムが失敗しない可能性を高めるためだと思いますが、それは問題ではありません。

callocと同じですmallocが、ゼロはメモリを初期化します。Linux にメモリのページを要求すると、Linux はすでにそれをゼロで初期化しています。したがって、calloc要求したメモリがカーネルから要求されたものであることがわかった場合、実際にゼロ初期化する必要はありません! そうでないため、そのメモリへのアクセスはなく、実際よりも多くのメモリを要求できるはずです。

コメントで述べたように、この回答は非常に良い説明を提供します。

于 2013-11-03T10:04:43.050 に答える
2

メモリに書き込む必要があるかどうかcallocは、プロセスに既に割り当てられているヒープ ページから割り当てを取得したか、カーネルによってプロセスに割り当てられるメモリを増やすように要求する必要があったかによって異なります (sbrk()またはなどのシステム コールを使用mmap())。カーネルが新しいメモリをプロセスに割り当てるときは、必ず最初にゼロにします (通常は VM の最適化を使用するため、実際にページに書き込む必要はありません)。ただし、以前に割り当てられたメモリを再利用している場合は、それを使用memset()してゼロにする必要があります。

于 2013-11-03T10:07:01.913 に答える
1

引用された複製またはここでは言及されていません。Linux は仮想メモリを使用し、システムで物理的に利用可能なより多くのメモリを割り当てることができます。ユーザー空間に単純にプラスcalloc()を加える単純な実装は、すべてのページに影響を与えます。malloc()memset()

Linux は通常 4k チャンクで割り当てるため、すべてのcalloc()ブロックは同じであり、最初はゼロとして読み取られます。つまり、同じ 4k のメモリ チャンクを読み取り専用calloc()にマップでき、スペース全体は約size/4k * pointer_size + 4k. プログラムがスペースに書き込むとcalloc()、ページ フォールトが発生し、Linux は新しいページ (4k) を割り当ててプログラムを再開します。

これは、コピー オン ライトまたは略して COWと呼ばれます。malloc()通常は同じように動作します。小さなサイズの場合、「C」ライブラリはビニングを使用し、4k ページを他の小さなサイズの割り当てと共有します。

そのため、通常は 2 つのレイヤーが関係しています。

  1. Linux カーネルのプロセス メモリ管理。
  2. glibcヒープ管理。

要求されたメモリ サイズが大きく、プロセスに割り当てる新しいメモリが必要な場合は、上記のほとんどが適用されます (Linux のプロセス メモリ管理による)。ただし、要求されたメモリが小さい場合は、malloc()プラスのようになりますmemset()。割り当てサイズが大きいmemset()と、メモリに接触し、カーネルが割り当てるには新しいページが必要であると判断するため、ダメージが大きくなります。

于 2013-11-04T17:14:36.807 に答える
0

カーネルが-ingmalloc(3)を実行するプロセスに与える以上の RAM を使用することはできません。割り当てたいメモリ量を割り当てることができない場合は、NULL を返します。さらに、とは、カーネルではなく、c ライブラリ ( ) によって定義されます。Linux カーネルは、ファミリではなく、およびその他の低レベルのメモリ割り当て関数を定義します(を除く)。malloc(3)malloc(3)malloc(3)memset(3)libc.sommap(2)*alloc(3)kalloc()

于 2013-11-03T10:01:17.897 に答える