最近のシステムでは、fork システム コールが使用されているという理由だけで、メモリが実際にコピーされることはありません。ページテーブルではすべて読み取り専用とマークされているため、最初にカーネルコードにトラップを書き込もうとすると発生します。最初のプロセスが書き込みを試みた場合にのみ、コピーが行われます。
これはコピー オン ライトと呼ばれます。
ただし、コミットされたアドレス空間も追跡する必要がある場合があります。カーネルがページをコピーする必要があるときにメモリまたはスワップが利用できない場合、メモリを解放するためにいくつかのプロセスを強制終了する必要があります。これは常に望ましいとは限らないため、カーネルがコミットしたメモリ量を追跡することは可能です。
カーネルが利用可能なメモリ + スワップよりも多くコミットする場合、fork を呼び出そうとするとエラー コードが返される可能性があります。十分な量が利用可能な場合、カーネルは fork 後に両方のプロセスの親の完全な仮想サイズにコミットします。
心配はいりません。遅延コピー (コピー オン ライト) が作成されます。両方のプロセスの仮想メモリ アドレスは、最初は同じページを指していますが、フォークされたプロセスがそれを変更しようとすると、実際にはページの物理コピーが作成されます (それ以降、そのページは RAM の 2 つの場所に存在します)。 /P>
報告されたメモリ フットプリントのいずれも、実際にプロセスが使用している RAM の量を示していないことに注意してください。スワッピング、メモリ共有、および仮想メモリに関するその他の問題のため、確実に知ることは不可能です。メモリ空間の一部は共有ライブラリであり (どこでカウントするか?)、一部は非 RAM メモリ (他のハードウェア デバイス) を参照し、一部は現在スワップアウトされており、一部はまだコピーされていません (コピー オン ライト)。すぐ。これを読んでください:
https://lwn.net/Articles/642202/
カーネル設定あり
/proc/sys/vm/overcommit_memory
優れた記事からの引用:
Since 2.5.30 the values are: 0 (default): as before: guess about how much
overcommitment is reasonable, 1: never refuse any malloc(), 2: be precise
about the overcommit - never commit a virtual address space larger than swap
space plus a fraction overcommit_ratio of the physical memory. Here
/proc/sys/vm/overcommit_ratio (by default 50) is another user-settable
parameter. It is possible to set overcommit_ratio to values larger than 100.
(See also Documentation/vm/overcommit-accounting.)
これは通常の malloc だけでなくフォークにも当てはまります。つまり0 に設定すると、フォークは書き込み時にコピーされます。コピー オン ライトとは、アプリがフォークされると、両方のコピーが子を使用してメモリ ページを共有するか、オリジナルがメモリの変更を開始することを意味します。
ほとんどのディストリビューションでは、overcommit が 0 であることを知っています。しかし、2 に設定すると、すべてのメモリ ページが実メモリによって完全にバックアップされ、場合によっては高いメモリ プレッシャーの下でより安定しますが、依存する一部のプログラム (私は gitk に直面)オーバーコミットでは失敗します。