2010-12-01 8 views
8

以前に使用されていたメモリのために私のプロセスに仮想アドレス空間を予約したいが、現在は必要ない。私は、ホストカーネルがLinuxであり、オーバーコミット(すべてのコミットされたメモリの詳細なアカウンティングによって行われる)を防ぐように設定されている状況に興味があります。mmap/mprotect-readonlyゼロページはコミットされたメモリにカウントされますか?

私のアプリケーションが物理メモリを占有していないか、ディスクにスワップされている(どちらの方法でもリソースを浪費している)のを防ぐには、madviseカーネルに不要であるか、mmap新しいゼロページオーバーそれの上に。しかし、これらのアプローチのどちらも、必然的にコミットされたメモリの量を減らすことはなく、他のプロセスは使用できなくなります。

ページを読み込み専用のゼロページに置き換えるとどうなりますか?私の意図は、彼らがコミットされたメモリにカウントされていないことです。さらに、後でmprotectを使用して書き込み可能にし、書き込み可能にするとコミットされたメモリ制限を超えた場合に失敗します。私の理解は正しいのですか?これは使えますか?

+1

読み取り専用のページは、プロセスのコミットチャージで考慮されるべきではありません(私は手元にありませんので、これは答えではありません)。LinuxはMAP_NORESERVEフラグを提供します。保証。しかし、私は尋ねる必要があります:あなたはなぜ使用していないメモリを予約する必要性を感じますか? – Anon

+0

プログラムが気がつかないうちに、同じ仮想アドレスが(mmapによって)ランダムに割り当てられた場合、Bad Things(tm)が発生します。 :-) 'MAP_NORESERVE'については、あとで書き込み可能にした後でも、ページの数がカウントされないように心配です。私はちょうど新しいゼロページを使ってそれらを再び「張る」ことができると思います。 –

+0

どのような悪いことが起こるでしょうか?なぜあなたのプログラムは以前に使われたアドレス空間を再利用する必要がないのですか?それは非常に珍しいようです。 – Angus

答えて

1

ページを使用していない(読み書きしている)場合は、自分のアドレススペースにコミットされません(予約されているだけです)。

あなたのアドレススペースは限られているので、あなたはそれを好きなようにプレイすることはできません。

"nul page/guard page"(アクセスのない匿名メモリ)の挿入のために、多数の割り当てに失敗する可能性のあるElectricFenceを参照してください。 は、これらのスレッドを見てください:「失敗のmprotectを():メモリーを割り当てることができません」:Linuxの http://thread.gmane.org/gmane.comp.lib.glibc.user/538/focus=976052

+3

* *は仮想サイズに課金されますが、RSSには課金されません。 –

1

を、オーバーコミットが無効になっていないと仮定すると、あなたがそのページを確実になる、mmapMAP_NORESERVEフラグを使用することができます問題になっているものは、アクセスする前に割り当てられたメモリとしては考慮されません。オーバーコミットが完全に無効になっている場合は、以下のマルチプルマッピングページを参照してください。

ゼロページのLinuxの動作が過去に変更されていることに注意してください。いくつかのカーネルバージョンでは、ページを読むだけで割り当てられます。他の人とは、書き込みが必要です。保護フラグは直接割り当てを引き起こさないことに注意してください。ただし、誤って割り当てを開始することを防ぐことができます。したがって、最も信頼できる結果を得るには、でmprotectと入力してください。

別の携帯可能なオプションとして、同じページを複数の場所にマップすることができます。つまり、空の一時ファイルを作成して開き、ftruncateを適当な数のページにリンクし、次にmmapをオフセット0で繰り返しファイルにリンクします。これは、メモリがプログラムのメモリ使用量に対して1回だけカウントされることを絶対に保証します。ページに書き込むときには、MAP_PRIVATEを使用して自動再割り当てすることもできます。

これは、MAP_NORESERVE手法(カーネルトラッキングデータと一時ファイル自体の両方)よりもメモリ使用量が多い可能性がありますので、代わりにMAP_NORESERVEを使用することをお勧めします。この手法を使用する場合は、マップされる領域を適度に大きくしてください(実際のディスクIOを避けるために、Linuxの場合は/dev/shmに入れてください)。個々のmmapコールは、それを追跡するために一定量の(スワップ不可能な)カーネルメモリを消費するので、そのカウントダウンを維持するとよいでしょう。

+1

有用な情報ですが、 'MAP_NORESERVE'は有用ではありません。オーバーコミットが完全に無効になっている場合は無視されます。 –

+0

'/ dev/zero'マッピングはあなたの提案の一時ファイルと同様に機能すると思いますか? –

+0

@Zan、no。 '/ dev/zero'マップは通常の' MAP_ANON'マップと同じですので、他のメモリ割り当てと同様に考慮されます。 – bdonlan

関連する問題