これは古い記事ですが、私はここで自分の考えを述べる自由をまだとっています。
Linuxは最初からメモリをページに分割します(通常、x86_64システムではページごとに4K)。その後、仮想メモリが作成され、そのマッピングは、MMU(メモリ管理ユニット)を使用して物理メモリで行われます。
プロセスには仮想メモリ領域からメモリが割り当てられるため、/ proc / meminfoを表示すると、仮想メモリの詳細としてVMalloc *が表示されることに注意してください。
メモリを要求するプロセスがあるとしましょう(300MB-Webブラウザなど)。プロセスには、仮想メモリから300MBが割り当てられますが、メモリがマップされている(物理メモリにマップされている)必要はありません。メモリ管理には「コピーオンライト」の概念があります。これにより、プロセスが仮想メモリから割り当てられたメモリを実際に使用する場合(つまり、メモリに何らかの書き込みを行う場合)、物理メモリにマップされます。これにより、マルチプロセス環境でカーネルが効率的に正しく動作するようになります。
キャッシュとは何ですか?
プロセスで使用される多くのメモリが共有されます。glibcライブラリがほとんどすべてのプロセスで使用されているとしましょう。すべてのプロセスが同じメモリ位置にアクセスしてジョブを実行できるときに、glibcの複数のコピーをメモリに保持するポイントは何ですか。このような頻繁に使用されるリソースはキャッシュに保持されるため、プロセスが要求したときに同じメモリロケーションを参照できます。これは、ディスクからglibc(etc。)を何度も何度も読み込むのに時間がかかるため、プロセスの高速化に役立ちます。
上記は共有ライブラリについての例でしたが、ファイル読み取りについても同様です。大きなファイル(100〜200MBなど)を初めて読み込む場合は、時間がかかります。ただし、同じ読み取りを再度試行すると、高速になります。データはメモリにキャッシュされ、すべてのブロックで再読み取りは行われませんでした。
バッファーとは
バッファに関する限り、プロセスがファイルI / Oを実行する場合、カーネルのバッファに依存してデータをディスクに書き込みます。プロセスは、ジョブを実行するようカーネルに要求します。そのため、プロセスに代わって、カーネルはデータを「バッファー」に書き込み、書き込みが完了したことをプロセスに伝えます。非同期的に、カーネルはバッファー内のこのデータをディスクに同期し続けます。このように、プロセスはデータをディスクに同期するための正しい時間を選択するためにカーネルに依存しており、プロセスは先に進み続けることができます。これは、通常のプロセスが実行している一般的なI / Oであることに注意してください。ただし、I / Oが実際にディスク上で実行されることを確認する必要がある特殊なプロセスは、ディスク上でI / Oを実行するために他のメカニズムを使用できます。オープンソースユーティリティの一部はlibaioです。また、プロセスコンテキストで開かれたFDに対して明示的な同期を呼び出す方法があります。
ページ違反とは何ですか?
バイナリが約300MBのプロセス(Webブラウザーなど)を開始するときの例を考えてみましょう。ただし、完全な300MBのWebブラウザーバイナリはすぐには動作しません。プロセスは、コード内で関数から関数に移動し続けます。前述のように、仮想メモリは300MB消費されますが、すべてがメモリに物理メモリにマップされるわけではありません(RSS-常駐メモリは少なくなります、上の出力を参照)。コード実行が実際に物理的にマップされていないポイントに達すると、ページフォールトが問題になります。カーネルはこのメモリを物理にマップし、メモリページをプロセスに関連付けます。このようなページフォールトは「マイナーページフォールト」と呼ばれます。同様に、プロセスがファイルI / Oを実行すると、メジャーページフォールトが発生します。
スワップアウトが発生するタイミングと理由
状況1:
上記の詳細に沿って、適切な量のメモリがメモリマッピングされるシナリオを考えてみましょう。そして今、プロセスが起動しますが、これにはメモリが必要です。上記で説明したように、カーネルはメモリマッピングを行います。ただし、メモリをマップするのに十分な物理RAMがありません。これで、カーネルは最初にキャッシュを調べ、使用されていない古いメモリページをいくつか持つことになります。これらのページを別のパーティション(SWAPと呼ばれる)にフラッシュし、一部のページを解放し、解放されたページを新しい要求にマップします。ディスクへの書き込みはソリッドステートRAMよりもはるかに遅いため、このプロセスには多くの時間がかかり、そのためスローダウンが発生します。
状況2:
システムで使用可能な空きメモリがたくさんあるとしましょう。それでも、多くのスワップアウトが発生していることがわかります。メモリの断片化の問題が発生する可能性があります。カーネルに50MBの連続したメモリを必要とするプロセスを検討してください。(連続して心に留めてください)。明らかに、カーネルはページを異なるプロセスにランダムに割り当て、それらのいくつかを解放します。ただし、連続したメモリを要求する場合、プロセスの要求を満足させるチャンクを探す必要があります。そのようなメモリを取得できない場合は、いくつかの古いメモリページをスワップアウトしてから、連続したページを割り当てる必要があります。そのような場合でも、スワップアウトが発生します。Kernel ver 2.6以降では、このような断片化の問題は大幅に減少しています。ただし、システムが長時間実行されている場合は、このような問題が引き続き発生する可能性があります。
この例を参照(vmstat出力)
2016-10-29 03:55:32 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
2016-10-29 03:55:32 r b swpd free buff cache si so bi bo in cs us sy id wa st
2016-10-30 03:56:04 19 23 2914752 4692144 3344908 12162628 1660 1 8803 12701 4336 37487 14 7 40 38 0
2016-10-30 03:56:34 3 20 2889296 4977580 3345316 12026752 2109 2 8445 14665 4656 36294 12 7 46 34 0
2016-10-30 03:57:04 1 11 3418868 4939716 3347804 11536356 586 4744 2547 9535 3086 24450 6 3 59 33 0 <<<-----
2016-10-30 03:57:34 3 19 3456252 5449884 3348400 11489728 3291 13371 6407 17957 2997 22556 6 4 66 24 0
2016-10-30 03:58:04 7 6 4194500 5663580 3349552 10857424 2407 12240 3824 14560 2295 18237 4 2 65 29 0
2016-10-30 03:58:34 2 16 4203036 5986864 3348908 10838492 4601 16639 7219 18808 2575 21563 6 4 60 31 0
2016-10-30 03:59:04 3 14 4205652 6059196 3348760 10821448 6624 1597 9431 4357 1750 20471 6 2 60 31 0
2016-10-30 03:59:34 2 24 4206968 6053160 3348876 10777216 5221 2067 10106 7377 1731 19161 3 3 62 32 0
2016-10-30 04:00:04 0 13 4205172 6005084 3348932 10785896 6236 1609 10330 6264 1739 20348 4 2 67 26 0
2016-10-30 04:00:34 4 11 4206420 5996396 3348976 10770220 6554 1253 10382 4896 1964 42981 10 5 58 27 0
2016-10-30 04:01:04 6 4 4177176 5878852 3348988 10825840 8682 765 10126 2716 1731 32949 8 4 69 19 0
@ 2016-10-30 03:57:04、利用可能な空きRAMがまだ十分にあることがわかります。しかし、それでもスワップアウトは起こりました。この時点でプロセスツリーを確認しましたが、このような大量のメモリ(空きメモリ以上)を必要とするプロセスが起動することはありませんでした。明白な疑いは、上記の状況2でした。上記のbuddyinfoおよびzoneinfoログを確認しました(echo m> / proc / sysrq-triggerを使用してこれらを確認し、出力はsyslogに記録されます)。
私たちの通常のシステムでは、ゾーン情報の比較はこれになります。また、cache / free / low memのグラフについても以下で説明します
情報を見ると、ノード0およびノード1の通常のメモリフラグメンテーションがあることが明らかです(ノードはNUMAベースのマシンであるため、複数のノードです(システムの情報を確認するにはnumactlを参照)。
メモリの断片化は、空きメモリがある場合でもスワップの使用量が増加する理由でもあります。