web-dev-qa-db-ja.com

ギガバイトの空きメモリがある場合、上部には「swout」(スワッピング)が表示されます。どうして?

ギガバイトの空きメモリがあるのに、なぜ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

  1. これがvm.swappinessの影響を受けるかどうかは明らかではありません。その設定は、キャッシュの再利用とキャッシュの再利用のバランスを取ります。スワッピング。ただし、freeメモリがたくさんあるのに、そもそもなぜメモリを再利用する必要があるのでしょうか。

  2. ご覧のとおり、これは小さなシステムです。 NUMAは使用しません。 /proc/zoneinfoをチェックインしましたが、ノードは「ノード0」だけです。したがって、これは NUMAによって引き起こされる ではありません。

  3. 関連する質問と回答には、「日和見スワッピング」、「システムに他に何もすることがない場合」、「後でメモリが不足した場合にメリットが得られる可能性がある」などのアイデアが記載されています。これらのアイデアは信頼できるものではありません。カーネルのドキュメントと矛盾します。 Linuxは「日和見スワッピング」を実行しますか、それとも神話ですか? を参照してください。

  4. RAM systemd.resources機能を使用した使用量に制限はありません。つまりすべてのsystemdユニットにはRAM使用量制限があると思います「無限大」に設定します。

    $ systemctl show '*' | \
        grep -E '(Memory|Swap).*(Max|Limit|High)' | \
        grep -v infinity
    $
    
  5. 編集:これは透明な巨大なページに関連していると思います。仮想マシンは、透過的な巨大ページを使用してゲストメモリを効率的に割り当てることに注意してください。それらは巨大なページを使用する唯一のユーザープログラムです 私のシステムでは

    似たような質問があります: 空きメモリが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 \{\} \;
$
2
sourcejedi

私は同様の質問について熟考していました-あなたはkswapdとゾーン透かしについての私のスレッドを見ました-そして私の場合(そしておそらくあなたの場合も)の答えはメモリの断片化です。

メモリが十分に断片化されると、高次の割り当てが失敗し、これは(追加の要因の数に応じて)直接再利用につながるか、ゾーンの再利用/圧縮を試みるkswapdをウェイクアップします。あなたは私のスレッドでいくつかの追加の詳細を見つけることができます。

このような問題に対処するときに注意を逃れる可能性のあるもう1つのことは、メモリゾーニングです。つまり十分なメモリがあるかもしれません全体(そしてそれは十分な連続したチャンクを含むかもしれません)が、DMA32に制限されるかもしれません(64ビットアーキテクチャを使用している場合)。 DMA32を「小さい」と無視する傾向がある人もいますが(おそらく32ビットの考え方に慣れているため)、4GBは実際には「小さい」わけではありません。

あなたのケースで何が起こっているのかを確実に知るには2つの方法があります。 1つは統計の分析です。/proc/buddyinfo、/ proc/zoneinfo、/ proc/vmstatなどの定期的なスナップショットを取得するようにジョブを設定し、表示されている内容を理解しようとすることができます。

もう1つの方法は、動作させるとより直接的で信頼性が高くなります。スワップアウトイベントにつながるコードパスをキャプチャする必要があり、カーネルにインストルメントされたトレースポイントを使用してキャプチャできます(特に、多数のvmscanイベントがあります)。

ただし、低レベルのインストルメンテーションは、箱から出してすぐに想定どおりに機能するとは限らないため、機能させるのは難しい場合があります。私の場合、ftraceインフラストラクチャのセットアップに時間を費やして、最終的に必要なfunction_graphプローブが何らかの理由で機能していないことを確認する必要がありました。次に試したツールはperfでしたが、最初の試みでも成功しませんでした。しかし、最終的に関心のあるイベントをキャプチャすることができた場合、それらはどのグローバルカウンターよりもはるかに速く答えにつながる可能性があります。

よろしく、ニコライ

2
Nikolai