SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

性能改善ノウハウを現場から直送! NTTデータのよりぬき『週刊まかせいのう』

Linux OSリソースのパフォーマンス分析(2) ~ CPUとメモリの使用状況を分析してみよう

性能改善ノウハウを現場から直送! NTTデータのよりぬき『週刊まかせいのう』 第6回

  • X ポスト
  • このエントリーをはてなブックマークに追加

メモリ使用状況の分析

メモリは、ユーザアプリケーションやカーネルを実行するために必要なリソースです。Linuxにおけるメモリ管理の仕組みは複雑で、その仕組みはカーネルのバージョンアップとともに改良されています。ここではメモリ使用状況を分析するにあたって、ポイントとなるいくつかの考え方を紹介します。

まず、メモリ使用状況について誤解されやすい点について触れておきます。

Linuxは、メモリに空きがあれば可能な限りディスクキャッシュとして確保することで、次回以降の読み込みを高速化しています。このキャッシュ確保によって空きメモリ(MemFree)が少なく見えますが、空きメモリ不足時にはカーネルの判断でキャッシュが解放され、空きメモリとして再利用できます。また、Javaアプリケーションなどでは、アプリケーションが使用するメモリの最小/最大サイズを指定できますが、実際に使用されるメモリは、アプリケーションが割り当てたメモリにデータを書き込んだ分となります。

このような特性から、メモリはCPUとは異なり、必ずしもスループットに比例してメモリ使用量が増加するわけではありません。メモリ使用状況を分析する際には、システム負荷の平常時とピーク時で比較することが望ましいです。

利用可能メモリについて

メモリ使用状況について、性能観点で特に意識しておきたいのは利用可能なメモリです[5]。空き(未使用な)メモリが不足すると、必要なメモリを確保するため、カーネルの判断で次のような動作が行われます。

  • ディスクキャッシュの一部を解放
  • スラブキャッシュ(カーネルの各種資源のキャッシュ)の一部を解放
  • 利用頻度の低いメモリをディスクへスワップアウト
  • それでもメモリが確保できなければ、CPUやメモリ使用状況などから問題になりにくそうなプロセスを強制終了

スワップが頻発することで処理遅延を招くおそれがあることから、利用可能メモリを簡単に表現すると、

「空きメモリ+解放可能なキャッシュ」

ということになります。

なお、全てのキャッシュを解放可能と見なすことは、性能観点からは望ましくないと考えられます。この理由は2つあります。

1つは、キャッシュサイズが小さくなると、キャッシュを利用する処理で遅延するおそれがあるためです。また、このような状況下ではカーネルの判断によって、キャッシュを解放せずにスワップアウトが選択されることがあります。

もう1つは、キャッシュの解放待ちに伴う処理遅延です。WriteI/Oによって更新されたキャッシュはDirtyと呼ばれ、まだディスクに書き込みが完了していない状態です。このDirtyなキャッシュを解放する際には、ディスク書き込みが完了するまで待ちが発生します。

それでは、このような仕組みを念頭において、メモリ使用状況を確認していきましょう。

[5]: ここでいう利用可能メモリとは、すでに使用中のメモリは含めません。

大まかなメモリ使用状況の分析

vmstatは、CPU、メモリ、ストレージに関する情報を出力するコマンドです。取得粒度が粗いため詳細な分析には不向きですが、大まかなメモリ使用状況をリアルタイムに確認する用途に向いています。

実行コマンド
vmstat 10 | awk '{print(strftime("%Y/%m/%d %H:%M:%S"),$0);fflush();}'
出力結果のサンプル テキスト表示
2015/10/26 13:13:57 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
2015/10/26 13:13:57  r  b   swpd   free  buff  cache    si   so    bi    bo   in   cs us sy id wa st
2015/10/26 13:13:57  1  0   3084 109320 124712 628832    0    0     0    28    0    0  0  0 100  0  0
2015/10/26 13:14:07  0  0   3084 108948 124712 629000    0    0     0   100  112  113  0  0 100  0  0
2015/10/26 13:14:17  0  0   3084 108940 124696 628976    0    0     0   108  111  113  0  0 100  0  0
2015/10/26 13:14:27  1  0   3084 109072 124712 629000    0    0     0   102   95  113  0  0 100  0  0
項目 意味
swpd スワップ領域の使用量(kB)
free 空きメモリ(kB)
buff メタデータ用キャッシュの使用量(kB)
cache ディスクキャッシュの使用量(kB)
si スワップインされた量(kB/秒)
so スワップアウトされた量(kB/秒)

※スワップインは、スワップ領域(ディスク)からメモリへ書き出す処理。スワップアウトは逆に、メモリからスワップ領域(ディスク)へ書き出す処理。

なお、vmstatコマンドが初回に出力するデータは、サーバ起動時からの平均値です。

大まかな利用可能メモリの算出

まずは、大まかな利用可能メモリとして「freecache」で算出し、安全率として8割程度で見ておくとよいでしょう[6]。この式は多少誤差を含むものの、利用可能メモリ不足をなるべく簡易にチェックすることを意図しています。厳密に見るとbuffも加算対象といえますが、cacheと比べるとbuffは相対的にサイズが小さいため、安全側に倒す意味でも加算は行わずに評価してよいでしょう。

より実態に近い利用可能メモリは、後述する/proc/meminfoから確認します。

[6]: RHEL7以降では「freecache」ではなく、/proc/meminfoのMemAvailableで利用可能メモリを確認してください。

分析のポイント

利用可能メモリに十分な余裕があるか

余裕の判断基準はシステム特性によりますが、基本的には物理メモリ総量の2割を下回っておらず、かつ今後アプリケーションが使用する可能性のあるメモリを確保可能かどうかで判断するとよいでしょう。例えば、Javaアプリケーションで使用する最大メモリサイズを6GBで設定しているけれども、まだ2GBしか使われていなければ、今後さらに4GB使用される可能性があります。

vmstatコマンドではOS全体のメモリ使用状況しかわかりませんが、ここからさらに、メモリ使用量の多いプロセスを特定するにはps -eF --sort=rssコマンドが便利です。

実行コマンド
ps -eF --sort=rss
出力結果のサンプル テキスト表示
UID        PID  PPID  C    SZ    RSS PSR STIME TTY          TIME CMD
root      2521     1  0  9734  32792   0 Dec03 ?        00:00:00 iscsiuio
oracle    3333     1  0 262892 34068   0 Dec03 ?        00:00:12 xe_lgwr_XE
gdm       4114  4011  0 75251  48320   0 Dec03 ?        00:00:00 /usr/libexec/gdmgreeter
root     32659     1  0 613773 54732   0 Dec08 ?        00:00:02 /usr/java/jdk1.8.0_65/bin/java -Dderby.system.home=/home/web
oracle    3520     1  0 260687 56844   0 Dec03 ?        00:00:11 xe_cjq0_XE
oracle    3349     1  0 260500 69088   0 Dec03 ?        00:00:19 xe_mmon_XE
oracle    3361     1  0 260245 79392   0 Dec03 ?        00:00:01 xe_s000_XE
root     30332     1  0 626351 112860  0 Dec04 ?        00:00:27 /usr/bin/java -Djava.util.logging.config.file=/home/tomcat/t
oracle    3341     1  0 260682 142436  0 Dec03 ?        00:00:27 xe_smon_XE
oracle    3329     1  0 264204 183620  0 Dec03 ?        00:00:35 xe_dbw0_XE
root     22892     1  1 698821 227684  0 Dec09 ?        02:21:27 /usr/java/jdk1.8.0_65/bin/jconsole
root     32663 32612  0 572295 510828  0 Dec08 ?        00:06:24 /usr/java/jdk1.8.0_65/bin/java -server -Xms256m -Xmx512m -XX
root     24770 24689  0 730598 561680  0 Dec07 ?        00:01:01 java -D[Standalone] -server -XX:+UseCompressedOops -verbose:

RSS(Resident Set Size)は、スワップされていない物理メモリ使用量(kB)を意味します。ps -eF --sort=rssコマンドは、RSSの昇順でプロセスの一覧を表示します。

なお、RSSの値は共有メモリを含んでおり、その分はプロセス間で重複カウントされます(単純にRSSを合算してもOS全体のメモリ使用量とは一致しません)。プロセス間共有メモリの使用量を確認するには、後述する/proc/meminfoの解説を参考にしてください。

利用可能メモリが時系列経過とともに減少しているか

利用可能メモリの減少傾向が見られる場合、メモリリークが発生している可能性があります。メモリ使用量が増加し続けているプロセスが存在するか確認しましょう。なお、スラブキャッシュが肥大化している可能性もあるため、後述する/proc/meminfoで詳細を確認します。

siおよびsoが頻発しているか

siおよびsoが頻発している場合(すなわち0でない値が定常的に計上されている場合)、メモリ不足が発生している可能性が高いです。スワップアウトは利用頻度の低いメモリをディスクに書き込むため、I/O待ちに伴う処理遅延を招くおそれがあります。

なお、利用可能メモリに余裕があるように見える状況でも、スワップアウトがたまに発生するケースがあります。これはカーネルの判断で、空きメモリやキャッシュをなるべく確保するため、利用頻度の低いメモリをスワップアウトしてるからです。この場合は、iostatコマンドの結果などでI/O待ちがとくに発生していなければ問題ありません。したがって、あくまで「siとsoの両方が」「定常的に」発生しているかどうかという観点で確認します。

次のページ
詳細なメモリ使用状況の分析

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
性能改善ノウハウを現場から直送! NTTデータのよりぬき『週刊まかせいのう』連載記事一覧

もっと読む

この記事の著者

若山 勝吾(株式会社NTTデータ 「まかせいのう」チーム)(ワカヤマ ショウゴ)

NTTデータの性能プロフェッショナルチーム「まかせいのう」の古参メンバ。12年前、大規模プロジェクトの性能課題に直面し、満身創痍になる日々を経験する。からくも性能改善できたときの喜びをきっかけに、現場の教訓とともに性能の道を歩むことを決意する。今では、50を超えるプロジェクトにて、お客様とともに性能...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/9167 2016/02/26 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング