使用可能なメモリがギガバイトの場合、上部に「swout」と表示されます。なぜ?

使用可能なメモリがギガバイトの場合、上部に「swout」と表示されます。なぜ?

使用可能なメモリはギガバイトですが、なぜatop20,000ページ(80 MB以上)以上を交換すると表示されますか?

私はこれに関するパフォーマンスの問題を見つけられませんでした。私はこの機会を通して知識を増やしたかったのです:-)。

atop10秒ごとに更新されます。更新するたびに、最後の更新以降のアクティビティが表示されます。

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  ^

カーネルメモリ情報:

$ 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。この設定は、キャッシュ除去とスワッピングのバランスを保ちます。しかし、たくさん無料覚えて、もしそうなら、もともと記憶を取り戻さなければならないのはなぜですか?

  2. ご覧のとおり、これは小さなシステムです。 NUMAを使用しません。チェックインした結果、/proc/zoneinfo「Node 0」ノードが1つしかないことがわかりました。だからこれはありませんNUMAが原因で発生しました

  3. 関連する質問と回答には、「機会的スワッピング」、「システムが何をすべきか」、「後でメモリ不足が発生した場合」などのアイデアが挙げられます。私はこれらのアイデアがカーネル文書と矛盾しているので信頼できないと思います。バラより Linuxは「機会交換」を行うのか、それとも神話なのか?

  4. この機能を使用するときは、RAM使用量に設定された制限はありませんsystemd.resources。つまりsystemd、すべてのデバイスのRAM使用制限が「無制限」に設定されているようです。

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

    同様の質問があります:利用可能なメモリがPages_high透かしよりはるかに高い場合、kswapdを有効にできますか?私はすべてのアプリケーションで大きなページをサポートするRHEL 6について尋ねています。

この結果を再現する方法がわからない。

これは、仮想マシンの起動時に発生します。 libvirtを使用して仮想マシンを実行します。デフォルトでは、VMディスクの読み取りはホストページキャッシュを使用してキャッシュされます。 (キャッシュモード:「ハイパーバイザーのデフォルト」は「書き込み保存」を意味します)。

仮想マシン、FADVISE_DONTNEEDイメージファイルを停止して再試行しました。しかし、同じことは起こりませんでした。

その後、別の仮想マシンで再試行しましたが、この問題がしばらく発生しました。私はそれを捕まえたvmstat。私は「swout」が違う、より高い数字を表すものだと思いましたが、atopそれをキャッチできませんでした。

$ 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

systemdまた、libvirtが迂回して誤って自己スワップする場合に備えて、VMのcgroupメモリ制限も確認しました。

$ 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 \{\} \;
$

答え1

私は同様の問題について考えていました。 kswapdとエリア透かしに関する私の投稿を見たことがあります。私の場合(そしておそらくあなたの場合でも同様)の答えはメモリの断片化でした。

メモリが十分に断片化されると、高次の割り当てが失敗し(他の多くの要因に応じて)直接回収が発生するか、kswapdが起動し、領域の回収/圧縮を試みます。私の投稿でいくつかの追加の詳細を見ることができます。

この問題に対処するときに見落とされる可能性があるもう1つのことはメモリです。分割。つまり、おそらく十分なメモリがあります。包括的な(十分な連続ブロックを含めることもできます。)しかし、DMA32に制限される可能性があります(64ビットアーキテクチャを使用している場合)。一部の人はDMA32を「小さい」と無視する傾向がありますが(おそらく32ビットの考えに慣れているため)、4GBは実際には「小さい」ということではありません。

あなたの出来事で何が起こったのかを判断する方法は2つあります。一つは、統計を分析することです。 /proc/buddyinfo、/proc/zoneinfo、/proc/vmstatなどの定期的なスナップショットを撮るようにタスクを設定し、現在見ているものを理解しようとすることができます。

機能すると、別のアプローチがより簡単で信頼性が高くなります。スワップイベントにつながるコードパスをキャプチャする必要があり、カーネルインスツルメンテーショントレースポイントを使用してこれを実行できます(特にvmscanイベントがたくさんあります)。

ただし、低レベルの機器が必ずしも元のように機能するわけではないため、それを操作するのは難しい場合があります。私の場合、ftraceインフラストラクチャを設定するのに少し時間がかかりましたが、最終的に私たちに必要なfunction_graphプローブが何らかの理由で機能しないことを発見しました。私たちが試した後、ツールはperfでしたが、最初の試みでも機能しませんでした。ただし、最終的に興味のあるイベントをキャプチャすると、どのグローバルカウンタよりも迅速に回答を得ることができます。

ありがとう、ニコラ

関連情報