
カーネル空間でメモリ リークが発生しているようです。スラブには、kmalloc-4096 がシステム上のすべての RAM リソースを独占してスワップを強制するまで、継続的に均等に増加していることが示されています。
Free では、このメモリ使用量の多くをキャッシュとして表示しますが、必要に応じて解放したり、手動でクリアするようにフラグが立てられた場合でも解放を拒否します。表示される内容の例:
$ sudo su -c "free -h && sync && echo 3 > /proc/sys/vm/drop_caches && free -h"
total used free shared buff/cache available
Mem: 15G 4.4G 166M 280M 10G 104M
Swap: 15G 7.8G 8.1G
total used free shared buff/cache available
Mem: 15G 4.4G 186M 280M 10G 115M
Swap: 15G 7.8G 8.1G
リークがどこにあるかを判断するために kmalloc をプロファイリングする必要がありますか? もしそうなら、それをどのように実行すればよいでしょうか?
これは、Intel i5 Skylake 上の標準の Ubuntu 16.04 インストールです。
$ uname -a
Linux fire 4.4.0-78-generic #99-Ubuntu SMP Thu Apr 27 15:29:09 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
答え1
「sync」はバッファ/キャッシュを削減するのではなく、単にデータがブロック デバイスに移動することを要求するだけです。キャッシュのポイントは、データが RAM キャッシュに残ることです。drop_caches に 3 を送信しても、キャッシュが削除されるのを待つことはありません。「free」の前に「sleep 60」を追加できますか? これにより、free から報告する前にメモリをクリアする時間を確保できます。
「watch -n60 cat /proc/meminfo」を実行すると、メモリの増大している領域を表示できる場合がありますが、キャッシュとバッファだけがリークしているわけではありません。メモリを消費することで、それらは目的を果たし、システムの利用可能なリソースを最大限に活用しています。
プロセスがディスクにスワップされたとしても、必ずしも何か悪いことが起こったというわけではありません。そのプロセスがすべてのページを使用しておらず、アイドル状態になっている場合、カーネルは正しい処理を行っています。たとえば、Web サーバーでは、ユーザーがログアウトしたときに GNU screen で実行されている mutt のコピーの前に、www ルートのコンテンツが必要になる可能性が十分にあります。
カーネルがモジュールを通じて RAM を消費しているとまだ考えている場合は、次のコマンドを使用してこれをもう少し詳しく調べることができます。
awk '{ print $2" "$1 }' /proc/modules | sort -n
ZFS を使用していますか? これは RAM をかなり消費しますが、キャッシュと同様に、必要な場合に備えてディスク IO を RAM 内に保持しようとします。