fork()はLinuxのプロセスヒープ全体をすぐにコピーしますか?


30

fork()システムコールは、実行中のプロセスから子プロセスのクローン。2つのプロセスは、PIDを除いて同一です。

当然、プロセスがヒープに書き込むのではなく、ヒープから読み取るだけの場合、ヒープのコピーはメモリの大きな浪費になります。

プロセスヒープ全体がコピーされますか?書き込みのみがヒープコピーをトリガーするように最適化されていますか?

回答:


19

全体のは、fork()書き込みにはmmap /コピーを使用して実装されています。

これは、ヒープだけでなく、共有ライブラリ、スタック、BSSエリアにも影響します。

結果として、結果の2つのプロセス(親と子)が実際にメモリ範囲への書き込みを開始するまで、フォークは非常に軽量な操作であることを意味します。この機能は、フォークボムの致死性に大きく貢献します。ページの複製と差別化でカーネルが過負荷になる前に、プロセスが多すぎることになります。

最新のOSで、カーネルがハードコピーを実行する操作の例(デバイスドライバーは例外)を見つけるのは困難です。VM機能を採用するのは、はるかに簡単で効率的です。

execve()「バイナリ/ ld.so /その他もろもろ、実行に続いてのmmapください」本質的に-とVMは、RAM、実行するプロセスの実際の負荷を処理します。ローカルの初期化されていない変数は「ゼロページ」からmmapされます-ゼロを含む特別な読み取り専用コピーオンライトページ、ローカルの初期化された変数はバイナリファイル自体からmmapされます(コピーオンライト、再び)等


注目すべき例外の1つは、Javaプロセスです。検索「フォークJavaのメモリ」と、あなたは大きな影響を与える問題の数十見つけるサーバーJVMまたは埋め込まれたJVMを上クラッシュ無残小さなシェルコマンドを実行しようと、「メモリを割り当てることができません」、この問題は、全身である(これらは単にランダムリンクされている例外をJava環境へ)。このSOの回答は、JVMのガベージコレクターとJITコンパイラーがプロセスメモリの共有を妨げていると非難しています。
ホワイトウィンターウルフ

24

Linuxカーネルfork()は、呼び出されたときにCopy-on-Writeを実装します。syscallが実行されると、親と子が共有するページは読み取り専用としてマークされます。

読み取り専用ページで書き込みが実行されると、メモリは2つのプロセス間で同一ではなくなるため、コピーされます。したがって、読み取り操作のみが実行されている場合、ページはまったくコピーされません。


1
+1ありがとう!1.参照リンクを提供していただけますか?2.ヒープは完全にコピーされますか、それとも部分的にコピーされますか?
アダムマタン14

4
2.-ページ内:)カーネルは、「ヒープ」が何であるかをほとんど理解していません-カーネルの場合、それはlibcアロケーターが必要に応じて処理する単なるマップされたプライベートページの集まりです。
qdot 14

これは本当にフォークボムですか?このコードは、現在のプロセスをフォークするのではなく、fork()呼び出し後の次の命令からではなく、開始から実行する同じプログラムのインスタンスをより多く作成するようです。
sherrellbc 14年

@mmk参考までに、私はあなたの「興味深いサイドノート:」に非常に驚いたので、(Linux 3.2.0で)確認するためにテストしましたが、それは真実ではないようです。私/proc/self/pagemapは、テストの目的のために、仮想アドレスから物理ページへのマッピングを決定するために使用していました。予想どおり、孫と孫だけが共有ページを書き込む場合、親と元の子は引き続き共有ページを共有します。孫だけがプライベートコピーになります。
セラダ

@セラダ。うーん 私はどこかでこれを読んだことがあり、それが参照しているカーネルバージョン(おそらく古いバージョン)を覚えていないので、もはや有効ではないかもしれません。
mmk

10

Linuxはコピーオンライトを行います。以下のようforkに新しいプロセスを作成し、割り当てられたページは読み取り専用としてマークされ、親と子の間で共有されています。いずれかがページを変更しようとすると、ページフォールトが生成され、ページがコピーされ、ページテーブルが適切に調整されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.