GNU/Linux >> Linux の 問題 >  >> Linux

mmap:マップされたファイルはすぐにメモリにロードされますか?

はい、mmap はマッピングを作成します。通常、メモリにマップしたものの内容全体を読み取るわけではありません。これを行いたい場合は、mlock/mlockall システム コールを使用して、該当する場合、カーネルにマッピングの内容を RAM に読み込ませることができます。


いいえ、そうかもしれません。場合によります。

mmap を呼び出す 一般的に アプリケーションに対して、マップされたファイルのコンテンツがそのアドレス空間にあたかもマップされることを意味するだけです ファイルがそこにロードされました。または、あたかもファイルが実際にメモリ内に存在するかのように、それらがまったく同じであるかのように (これには、書き込みアクセス権があると仮定して、ディスクに書き戻される変更が含まれます)。

それ以上でもそれ以下でもありません。何かをロードするという概念はなく、アプリケーションはこれが何を意味するのかを知りません。

アプリケーションは、仮想メモリ システムによってそのように見えますが、実際にはメモリなどの知識を持っているわけではありません。アプリケーションが「参照」(およびアクセス) できるメモリは、実際の物理メモリに対応している場合と対応していない場合があります。これは原則として、事前の警告や明確な理由 (アプリケーションにとって明らか) なしにいつでも変更できます。
ページ フォールトによるわずかな遅延が発生する可能性があることを除けば、アプリケーションは (原則として) そのようなことが起こっていることをまったく認識しておらず、それをほとんど、またはまったく制御できません。

通常、アプリケーションは、障害が発生した結果として、マップされたファイル (メインの実行可能ファイルを含む) からページをオンデマンドでロードします。ただし、オペレーティング システムは通常、パフォーマンスを最適化するために投機的にデータをプリフェッチしようとします。

実際には、 mmap を呼び出します すぐに開始します マッピングの先頭から特定の実装指定サイズまでページを (非同期的に) プリフェッチします。つまり、原則として、小さなファイルの場合、答えは「はい」になり、大きなファイルの場合は「いいえ」になります。
ただし、mmap 先読みの完了を待つためにブロックしません。つまり、mmap の直後にファイルが RAM にあるという保証はありません。 返品します(いつでもその保証があるわけではありません!)。その限りでは、答えは「たぶん」です。

Linux では、前回見たとき、デフォルトのプリフェッチ サイズは 31 ブロック (~127k) でした。プリフェッチされた領域の近くまたは最後にあるページがタッチされると、より多くのページが非同期でプリフェッチされます。
MADV_RANDOM をほのめかした場合 madviseまで 、プリフェッチは「発生する可能性が低い」ため、Linux ではプリフェッチが完全に無効になります。

一方、 MADV_SEQUENTIAL を与えると ヒントは、マッピングの最初から「より積極的に」非同期にプリフェッチします (そして、アクセスされたページをより速く破棄する可能性があります)。 Linux では、「より積極的に」とは、通常の 2 倍の量を意味します。

MADV_WILLNEED を与える ヒントは、指定された範囲内のすべてのページができるだけ早く読み込まれることを示唆しています (ただし、保証はしません) (それらにアクセスすると言っているため)。 OS はこれを無視するかもしれませんが、Linux では、プロセスの最大 RSS 制限と実装指定の制限まで (私の記憶が正しければ、物理 RAM の量の 1/2 )。
MADV_DONTNEED に注意してください Linux では間違いなく間違って実装されています。ヒントは POSIX で指定された方法で解釈されません。つまり、ページがページアウトされても今のところ問題ありませんが、ページを破棄するつもりです。 .これは、読み取り専用のマップされたページには大きな違いはありません (問題ないと言った小さな遅延を除いて) が、重要 であることは確かです 他のすべてのために。
特に、 MADV_DONTNEED を使用して OS が不必要なページをディスクに遅延書き込みした後、Linux が不要なページを解放すると考える それは、物事の仕組みではありません !明示的に同期するか、サプライズに備える必要があります。

readahead に電話した mmap を呼び出す前のファイル記述子 (または、以前にファイルを読み書きしたことがある場合)、ファイルの内容は 実際 実際、すぐにRAMに入れます。
ただし、これは実装の詳細 (統合仮想メモリ システム) にすぎず、システムのメモリ プレッシャの影響を受けます。

mlock を呼び出す 成功すると仮定すると、要求されたページをすぐに RAM にロードします。すべてのページが物理的に存在するまでブロックされ、ロックを解除するまでページが RAM に保持されることが保証されます。

照会する機能が存在します (mincore ) 特定の範囲内の一部またはすべてのページがその瞬間に実際に存在するかどうか、および 希望 について OS にヒントを与える機能 確固たる保証なしで起こっていることを確認する (madvise )、最後にページの限られたサブセットを強制的にメモリに存在させる機能 (mlock ) 特権プロセス用。

権限がないことと、クォータまたは存在する物理 RAM の量を超えていることの両方のために、そうではないかもしれません.


デフォルトでは、mmap() はマッピングとリターンのみを構成します (高速)。

Linux (少なくとも) にはオプション MAP_POPULATE (「man mmap」を参照) があり、これはまさにあなたの質問の内容を実行します。


Linux
  1. バッシュ‘?

  2. MvはFsでアトミックですか?

  3. パターンが最初に発生した後にファイルを別のファイルに挿入しますか?

  1. Stdoutに出力し、同時にGrepをファイルに出力しますか?

  2. ファイルの内容を表示せずにクリップボードにコピーしますか?

  3. ファイルへの書き込みとマップされたメモリへの書き込みの違いは何ですか?

  1. Linux:「ユーザー名」が sudoers ファイルにありません。この事件は報道される

  2. ユーザーが sudoers ファイルにありません。この事件は報道される

  3. コマンドがユーザー入力を要求するときに、コマンドの出力をファイルにリダイレクトする方法は?