ギガバイトの空きメモリがあるのに、なぜatop
は、20,000ページ以上(80メガバイト以上)をスワップアウトしていることを示したのですか?
これに関するパフォーマンスの問題には気づいていません。私は単に私の知識を増やす機会を利用したいと思っています:-)。
atop
は10秒ごとに更新されます。各更新には、最後の更新以降のアクティビティが表示されます。
MEM | tot 7.7G | free 3.7G | cache 608.3M | buff 19.1M | slab 264.6M |
SWP | tot 2.0G | free 1.4G | | vmcom 13.4G | vmlim 5.8G |
PAG | scan 167264 | steal 109112 | stall 0 | swin 0 | swout 23834 |
"swout" is non-zero and coloured in red ^
カーネルmeminfo:
$ head -n 5 /proc/meminfo
MemTotal: 8042664 kB
MemFree: 3563088 kB
MemAvailable: 3922092 kB
Buffers: 20484 kB
Cached: 775308 kB
カーネルバージョン:
$ uname -r
5.0.16-200.fc29.x86_64
これがvm.swappiness
の影響を受けるかどうかは明らかではありません。その設定は、キャッシュの再利用とキャッシュの再利用のバランスを取ります。スワッピング。ただし、freeメモリがたくさんあるのに、そもそもなぜメモリを再利用する必要があるのでしょうか。
ご覧のとおり、これは小さなシステムです。 NUMAは使用しません。 /proc/zoneinfo
をチェックインしましたが、ノードは「ノード0」だけです。したがって、これは NUMAによって引き起こされる ではありません。
関連する質問と回答には、「日和見スワッピング」、「システムに他に何もすることがない場合」、「後でメモリが不足した場合にメリットが得られる可能性がある」などのアイデアが記載されています。これらのアイデアは信頼できるものではありません。カーネルのドキュメントと矛盾します。 Linuxは「日和見スワッピング」を実行しますか、それとも神話ですか? を参照してください。
RAM systemd.resources
機能を使用した使用量に制限はありません。つまりすべてのsystemd
ユニットにはRAM使用量制限があると思います「無限大」に設定します。
$ systemctl show '*' | \
grep -E '(Memory|Swap).*(Max|Limit|High)' | \
grep -v infinity
$
編集:これは透明な巨大なページに関連していると思います。仮想マシンは、透過的な巨大ページを使用してゲストメモリを効率的に割り当てることに注意してください。それらは巨大なページを使用する唯一のユーザープログラムです 私のシステムでは 。
似たような質問があります: 空きメモリがpages_highウォーターマークをはるかに超えている場合、kswapdをアクティブにできますか? すべてのアプリケーションで巨大なページを有効にするRHEL6について質問しています。
この結果をどのように再現するか正確にはわかりません。
VMの起動時に発生しました。私はlibvirtを使用してVMを実行しています。デフォルトに従って、VMディスク読み取りはホストページキャッシュを使用してキャッシュされます(キャッシュモード:「ハイパーバイザーのデフォルト」は「ライトバック」を意味します)。
VM、FADVISE_DONTNEED
イメージファイルを停止して、再試行しました。しかし、同じことは起こりませんでした。
次に、別のVMで再試行しましたが、短時間発生しました。 vmstat
をキャプチャしました。 atop
は「swout」について別のより高い数値を示したと思いますが、私はそれをキャプチャしませんでした。
$ vmstat 10
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 770168 5034300 28024 936256 0 2 21 86 60 101 22 9 68 1 0
0 0 770168 5033852 28048 935904 0 0 0 8 372 633 1 1 97 0 0
1 0 770168 4974048 28252 948152 3 0 1137 194 1859 2559 11 7 79 3 0
0 1 770168 4557968 28308 1037512 0 0 8974 45 3595 6218 16 6 57 21 0
6 3 770168 4317800 28324 1111408 0 0 7200 609 6820 6793 12 5 38 44 0
0 4 770168 4125100 28348 1182624 0 0 6900 269 5054 3674 74 3 8 15 0
0 5 770168 3898200 27840 1259768 2 0 9421 630 4694 5465 11 6 11 71 0
1 3 770168 3760316 27672 1300540 0 0 9294 897 3308 4135 5 4 28 63 0
0 1 770168 3531332 27032 1356236 0 0 10532 155 3140 4949 8 5 63 25 0
0 0 783772 3381556 27032 1320296 0 1390 7320 4210 4450 5112 17 5 43 35 0
0 0 783772 3446284 27056 1335116 0 0 239 441 995 1782 4 2 92 2 0
0 0 783772 3459688 27076 1335372 0 0 3 410 728 1037 2 2 95 1 0
また、VMのcgroupメモリ制限、libvirtがsystemd
をバイパスした可能性、および誤ってそれ自体にスワッピングを加えたことを確認しました。
$ cd /sys/fs/cgroup/memory/machine.slice/machine-qemu\x2d5\x2ddebian9.scope
$ find -type d # there were no sub-directories here
$ grep -H . *limit_in_bytes
memory.kmem.limit_in_bytes:9223372036854771712
memory.kmem.tcp.limit_in_bytes:9223372036854771712
memory.limit_in_bytes:9223372036854771712
memory.memsw.limit_in_bytes:9223372036854771712
memory.soft_limit_in_bytes:9223372036854771712
$ cd ../..
$ find -name "*limit_in_bytes" -exec grep -H -v 9223372036854771712 \{\} \;
$
私は同様の質問について熟考していました-あなたはkswapdとゾーン透かしについての私のスレッドを見ました-そして私の場合(そしておそらくあなたの場合も)の答えはメモリの断片化です。
メモリが十分に断片化されると、高次の割り当てが失敗し、これは(追加の要因の数に応じて)直接再利用につながるか、ゾーンの再利用/圧縮を試みるkswapdをウェイクアップします。あなたは私のスレッドでいくつかの追加の詳細を見つけることができます。
このような問題に対処するときに注意を逃れる可能性のあるもう1つのことは、メモリゾーニングです。つまり十分なメモリがあるかもしれません全体(そしてそれは十分な連続したチャンクを含むかもしれません)が、DMA32に制限されるかもしれません(64ビットアーキテクチャを使用している場合)。 DMA32を「小さい」と無視する傾向がある人もいますが(おそらく32ビットの考え方に慣れているため)、4GBは実際には「小さい」わけではありません。
あなたのケースで何が起こっているのかを確実に知るには2つの方法があります。 1つは統計の分析です。/proc/buddyinfo、/ proc/zoneinfo、/ proc/vmstatなどの定期的なスナップショットを取得するようにジョブを設定し、表示されている内容を理解しようとすることができます。
もう1つの方法は、動作させるとより直接的で信頼性が高くなります。スワップアウトイベントにつながるコードパスをキャプチャする必要があり、カーネルにインストルメントされたトレースポイントを使用してキャプチャできます(特に、多数のvmscanイベントがあります)。
ただし、低レベルのインストルメンテーションは、箱から出してすぐに想定どおりに機能するとは限らないため、機能させるのは難しい場合があります。私の場合、ftraceインフラストラクチャのセットアップに時間を費やして、最終的に必要なfunction_graphプローブが何らかの理由で機能していないことを確認する必要がありました。次に試したツールはperfでしたが、最初の試みでも成功しませんでした。しかし、最終的に関心のあるイベントをキャプチャすることができた場合、それらはどのグローバルカウンターよりもはるかに速く答えにつながる可能性があります。
よろしく、ニコライ