プロセスが分岐するとき、その仮想メモリまたは常駐メモリはコピーされますか?


12

Linuxで新しいプロセスを作成する標準的な方法は、親プロセスのメモリフットプリントがコピーされ、それexecvが呼び出されるまで子プロセスの環境になることです。

仮想メモリ(プロセスが要求したもの)または常駐メモリ(実際に使用されているもの)について、どのメモリフットプリントについて話していますか?

動機:スワップスペースが限られたデバイスと、仮想メモリフットプリントと常駐メモリフットプリントに大きな違いがあるアプリケーションがあります。メモリ不足のため、アプリケーションは分岐できません。仮想フットプリントのサイズを小さくすることが役立つかどうかを確認したいと考えています。

回答:


12

現代のシステムでは、forkシステムコールが使用されているという理由だけで、実際にメモリがコピーされることはありません。ページテーブルではすべて読み取り専用とマークされているため、最初にトラップをカーネルコードに書き込もうとすると発生します。最初のプロセスが書き込もうとすると、コピーが発生します。

これはコピーオンライトとして知られています。

ただし、コミットされたアドレス空間も追跡する必要がある場合があります。カーネルがページをコピーするときにメモリまたはスワップが利用できない場合、メモリを解放するために何らかのプロセスを強制終了する必要があります。これは常に望ましいとは限らないため、カーネルがコミットしたメモリ量を追跡することが可能です。

カーネルが利用可能なメモリ+スワップ以上にコミットする場合、forkを呼び出そうとしたときにエラーコードが表示される可能性があります。十分な空きがある場合、カーネルは、分岐後の両方のプロセスの親の完全な仮想サイズにコミットします。


1
If enough is available the kernel will commit to the full virtual size of the parent for both processes after the fork.はい、ありがとうございます。つまり、メモリ(RAMおよびスワップ)が限られた環境でプロセスの仮想フットプリントを削減すると、フォークできないという問題を解決できる可能性があります。
TheMeaningfulEngineer

1
@アランはい。forkメモリ不足を示すエラーメッセージで失敗した場合。次に、フォークする前にプロセスの仮想メモリ使用量を減らすと役立ちます。
カスペルド

5

心配する必要はありません。遅延コピー(コピーオンライト)を作成します。両方のプロセスの仮想メモリアドレスは最初は同じページを指しますが、分岐したプロセスがそれを変更しようとすると、実際にページの物理コピーを作成します(それ以降、そのページはRAMの2つの場所に存在します)。

ただし、報告されたメモリフットプリントのどれも、実際にプロセスが使用しているRAMの量を示すものではありません。スワップ、メモリ共有、および仮想メモリに関するその他の問題のため、確実に知ることは不可能です。メモリスペースの一部は共有ライブラリ(それらをカウントする場所)、非RAMメモリを参照するもの(他のハードウェアデバイス)、現在スワップアウトされているもの、まだコピーされていないもの(コピーオンライト)、など。これを読む:

https://lwn.net/Articles/642202/


5

カーネル設定があります

/ 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に設定すると、フォークは書き込み時にコピーされます。書き込み時にコピーとは、アプリがフォークされると、両方のコピーがutil子または元のメモリページを共有することを意味します。

ほとんどのディストリビューションでは、オーバーコミットが0であることを知っています。ただし、2に設定すると、すべてのメモリページが実際のメモリによって完全にバックアップされ、場合によっては高いメモリプレッシャーでより安定しますが、依存する一部のプログラム(gitkに直面)オーバーコミットでは失敗します。

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