Yakstは、海外の役立つブログ記事などを人力で翻訳して公開するプロジェクトです。
9年以上前投稿 修正あり

Linuxで、どのプロセスがページングを行っているのか調べるには?

スワップがなぜ起きるか、どのようにスワップの状態を確認するべきかの平易な解説。Quoraの質問に対する、Robert Love氏の回答。

原文
Robert Love's answer to How can I determine which process is contributing to paging on Linux? - Quora (English)
原文ライセンス
Quora license
翻訳依頼者
D98ee74ffe0fafbdc83b23907dda3665
翻訳者
D98ee74ffe0fafbdc83b23907dda3665 doublemarket
原著者への翻訳報告
未報告


質問に対するストレートな回答は、調べるのは不可能、だ。どうしてそうなのかを説明してから、君の知りたい情報を含んでいるであろう、5つの関連する質問に答えよう。

Linuxのような、モダンなOSにおいては、スワップはシステム全体における現象だ。ある1つのプロセスがスワップに関する責任を持っているわけではない。システムがスワップしているかどうかは、メモリプレッシャの機能による。物理メモリを大量に使おうとすれば、スワップしてしまう。何をスワップアウトするかは、一番少ないページを要求しているのが何かによる。何をスワップインするかは、一番ページを必要としているのが何かによる。プロセスがRAM上に存在しないページを要求した時、そのページはディスク上にあるので、スワップが発生することになる。これが即ページングを起こすプロセスだが、これが全てのプロセスのメモリ消費の総計であるRAM領域の不足の原因となるわけではない。

重要なことなので繰り返して言おう。スワップを発生させる原因となるプロセスは、音楽が止まっても座る椅子がなさそうなヤツのことだ。彼は、君の椅子を全て使ってしまう太った豚かもしれないし、君のシステム上では最も小さなプロセスかも知れない。問題の核心は、君の持っている椅子よりたくさんの椅子が必要だということだ。すなわち、全ての椅子を使ってしまっている巨大なプロセスがいることが問題だ。しかし、もっとよくある簡単な話としては、君のワーキングセット、つまり君が何かするのに必要なメモリの量が、システム上のRAMの大きさを超えている場合だ。だからスワップが発生する。

ふむ、それでは、プロセスが使っているRAMを確認することで、システムがどのくらいメモリを要求しているのか、雰囲気をつかんでみよう。どうすればよいか? ps -auxを使って、RSS列を見ればいい。RSSは、各プロセスが使っているRAM(例、磁気メモリ)の量だ。RSSの値が大きいプロセスが、一番RAMを使っているプロセスということになる。

システム全体のメモリの状態を把握するにはどうしたらいいだろう? free -mコマンドを使えばいい。-/+ buffers/cache行を見よう。これが、I/Oバッファやページキャッシュ分をそれぞれ加減算した後の、システムの使用済みあるいはフリーなメモリの量だ。この行のfreeがゼロに近づいているなら、メモリ要求がRAMのサイズを超えつつあるので、スワップが始まるだろう。

どのくらいスワップを使っているか? これもfree -mを使おう。Swap行のusedを見ればよい。

スワップしたのはいつだろうか? そういう時はvmstatだ。siとsoの列はそれぞれ秒単位で、ディスクからRAMへ移動したメモリ量、あるいはRAMからディスクへ移動したメモリ量だ。vmstat 1を実行すれば、リアルタイムで情報が見られる。これでスワップの実態を確認できる。

各プロセスは、どのくらいスワップを使っているんだろうか?これに対しては、以下のスクリプトで、各プロセスがどのくらいディスクにスワップしているかを表示できる。

#! /bin/bash
#
# Page on Page on swap.sh: Shows the swap usage of each process
# Author: Robert Love

swap_total=0
for i in /proc/[0-9]*; do
  pid=$(echo $i | sed -e 's/\/proc\///g')
  swap_pid=$(cat /proc/$pid/smaps |
    awk 'BEGIN{total=0}/^Swap:/{total+=$2}END{print total}')
  if [ "$swap_pid" -gt 0 ]; then
    name=$(cat /proc/$pid/status | grep ^Name: |
      awk '{print $2}')
    echo "${name} (${pid}) ${swap_pid} kB"
    let swap_total+=$swap_pid
  fi
done

echo
echo "Total: ${swap_total} kB"

自分自身が所有するもの以外のプロセスの情報を見るため、このスクリプトはrootで実行する必要があるだろう。

次の記事
max_user_connectionsを設定して、MySQLのダウンタイムを回避しよう
前の記事
mysqlnd_msによるシンプルなMySQLのマスタHA

Feed small 記事フィード

新着記事Twitterアカウント