「詳解システムパフォーマンス」の読書メモシリーズ・第6弾。
- 詳解システムパフォーマンスを読んでいる話・2章/メソドロジ 読書メモ - えいのうにっき
- 読書メモ・詳解システムパフォーマンス 第3章/オペレーティングシステム - えいのうにっき
- 読書メモ・詳解システムパフォーマンス 第4章/可観測性ツール - えいのうにっき
- 読書メモ・詳解システムパフォーマンス 第5章/アプリケーション - えいのうにっき
- 読書メモ・詳解システムパフォーマンス 第6章/CPU - えいのうにっき
- 作者: Brendan Gregg,西脇靖紘,長尾高弘
- 出版社/メーカー: オライリージャパン
- 発売日: 2017/02/22
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る
感想
- また一ヶ月も間隔が開いてしまった...。。
- 引き続きおもしろい。いままで断片的に触れてきたところの穴埋めができたような感覚。
- ただ難しさを感じるところ、なかなか頭に入ってこないところもある。
- ex. スラブアロケータ、「無名xx」、リーピングとフリーリストの関係(関係ない?)
- 微妙な表現とかニュアンスのせいなのかもしれないけど、結局何を指しているのかがわかりにくいからだったり、頭の中でうまく関連付けられてなかったりしてるんだろうなー。
読書メモ
7.1 用語
- メインメモリ:物理メモリとも。一般に DRAM で提供される
- 仮想メモリ:メインメモリの抽象。実メモリではない。
- 常駐メモリ:現在メインメモリにあるメモリ。
- 無名メモリ:ファイルシステム位置やパス名を持たないメモリ。ヒープ(プロセスのアドレス空間内のワーキングデータ)を含む。
- ページ:OSとCPUが使うメモリの単位。伝統的に4kbや8kbが用いられる。
- ページフォルト:無効なメモリアクセス。オンデマンド仮想メモリを使うときには普通に発生する。
- ページング:メインメモリとストレージデバイスの間でのページの転送。
- スワッピング
- スワップ:ページングされる無名データやスワップされるプロセスのうち、ディスク上の部分。物理スワップデバイスであることもあれば、スワップファイルであることもある
7.2 コンセプト
7.2.1 仮想メモリ
- 仮想メモリ:各プロセスとカーネルに専用の、広大で線形なプライベートアドレス空間を提供する抽象。物理メモリ上での配置はOSに任せる。
- メインメモリの容量を越えてメモリを使えるようにするためのオーバーサブスクリプションをサポートしている。
- オーバーコミット:メインメモリと物理スワップデバイスのサイズの合計を越えてメモリのアロケーションを認める仕組み。
7.2.2 ページング
- 外部からメインメモリにページを移動することをページイン、メインメモリから外部に移動することをページアウトという。
- ファイルシステムページング
- ファイルシステムページのページングのための仕組み。メモリマップトファイルにページを読み書きする
- 無名ページング
7.2.3 デマンドページング
- デマンドページング:該当アドレスのメモリ内容が必要となった時点で、物理ページを論理ページに割り当てる方式のこと。CPUにかかるマッピング作成のオーバーヘッドを先延ばしにすることができる。
- マイナーフォルト:データがそのプロセスのアドレス空間にマッピングされていないものの、マッピングがメモリ内の他のページで満足させられるときのページフォルト
- メジャーフォルト:ストレージデバイスへのアクセスが必要なページフォルト
- 仮想メモリ内のページは、以下のいずれかの状態となる
7.2.4 オーバーコミット
7.2.5 スワッピング
7.2.6 ファイルシステムキャッシュ
- パフォーマンス向上のため、OSは使用可能メモリを使ってファイルシステムをキャッシングする
- ファイルシステムキャッシュは、アプリケーションがメモリを必要としたときにはすばやく開放されるものなので、未使用メモリとして扱える・これによるメモリ容量の逼迫は気にしなくて良い
7.2.7 使用率と飽和
- メインメモリが飽和状態になると、OSはページング、スワッピングを駆使してフリーメモリを作ろうとする
- Linux では OOM キラーも使われる
7.2.8 アロケータ
7.2.9 ワードサイズ
- メモリのパフォーマンスは、CPUのアーキテクチャ次第では、ワードサイズが大きい方が高くなる
- データ型が大きなサイズのワードの上位ビットに未使用部分を持つ場合には、メモリの一部が無駄になる。
7.3 アーキテクチャ
7.3.1 ハードウェア
- DRAM
- CAS(Column Address Strobe)レイテンシ
- メインメモリのアーキテクチャ
- 複数プロセッサUMAの場合、各CPUは共有システムバスを介して全てのメモリに対して一定のアクセスレイテンシでアクセスすることができる
- 複数プロセッサNUMAの場合、メインメモリに対するアクセス時間はCPUからの相対的な距離によって変わる。
- 別のCPUのインターコネクトを介してI/Oを実行する必要があるようなメモリのことをリモートメモリ、直接アクセスできる位置にあるメモリのことをローカルメモリと呼ぶ。
- メモリノード:個々のCPUに接続されているメモリのバンクのこと。
- OSは、プロセッサから得られる情報にもとづき、メモリノードのトポロジを意識し、出来る限りローカルメモリを使うようにする(メモリの局所性を尊重する)ようなメモリの配置をおこなう場合がある。
- バス
- DDR SDRAM
- Double Data Rate Synchronous Dynamic Random-Access Memory
- Double Data Rate:クロックシグナルのライズエッジとフォールエッジの両方でデータを転送すること。
- Synchronous:メモリのクロックがCPUのクロックと同期していること。
- マルチチャンネル
- 帯域幅の向上のため、複数のメモリバスを並列的に利用すること
- CPUキャッシュ
- MMU
- 複数のページサイズ
- TLB
- アドレス変換用のキャッシュ。
- 命令ページとデータページのために別々のキャッシュに分割できる
- TLBが持つマッピングエントリ数には限りがある
- 大きなページサイズを使うことでキャッシュで翻訳できるメモリの範囲が広がり、TLBミスが減りシステムのパフォーマンスが上がる。
7.3.2 ソフトウェア
- メモリの開放
- フリーリスト:すぐにアロケーションに回せる未使用ページのリスト。通常は、ローカリティグループ(NUMA)ごとにひとつずつのフリーページリストとして実装されている
- リーピング:メモリ枯渇の閾値を越えたとき、簡単に開放できるメモリを即刻開放させるための命令。カーネルモジュールとカーネルスラブアロケータが対象。
- ページキャッシュ:ファイルシステムキャッシュ。
swappiness
パラメータによって、スワッピングの実施ではなくページキャッシュからのメモリ解放の選択を優先する度合いを指定することもできる。 - スワッピング:
kswapd
(ページアウトデーモン)によるページング。最近使われていないページ(アプリケーションメモリも含む)を見つけてきてフリーリストに追加する。その後ページアウトされ、その結果としてスワップファイルかスワップデバイスへの書き込みを伴うこともある。 - OOMキラー:
select_bad_process()
で見つけたプロセスを強制終了することでメモリを開放する。 その際には/var/log/messages
内にOut of memory: Kill process
というメッセージとして出力もされる。 - Solaris では、ページングが発生するときはシステムキャッシュが空のときである一方で、Linux の場合は
swappiness
パラメータによりコントロールすることができる。
- フリーリスト
- 利用可能メモリをすぐに見つけられるようにするもの。
- 明示的に開放されたメモリは、今後のアロケーションで使えるようにリストの先頭に追加される
- 明示的な開放ではなく、ページアウトデーモンによって開放されたメモリはリストの末尾に追加される
- キャッシュされたファイルシステムページとしてまだ使える情報情報が含まれているため
- アロケートされ再利用されるまえにそのページに対するアクセスがあると、そのページはフリーリストからは削除されてキャッシュとして復活する
- バディアロケータ:Linuxにおいてページを管理するために使用されているアロケータ
- ページの近隣のフリーメモリを見つけて、それらをいっしょにアロケートできることから
バディ
とされている - さまざまなサイズのメモリアロケーションのために複数のフリーリストを管理している
- ページの近隣のフリーメモリを見つけて、それらをいっしょにアロケートできることから
- リーピング
- カーネルのスラブアロケータキャッシュからメモリを開放すること
- スラブアロケータキャッシュには、すぐに再利用可能なスラブサイズの未使用メモリ(チャンク)が含まれている
- カーネルのスラブアロケータキャッシュからメモリを開放すること
- ページスキャン
- フリーリストに含まれる利用可能メインメモリが閾値未満になった際に、ページアウトデーモンによっておこなわれるもの
- 非アクティブ/アクティブなメモリそれぞれのLRUページリストをスキャンする
- ページアウトデーモンはまず非アクティブリストをスキャンしてから、その後必要ならばアクティブリストをスキャンする
- ロックされていたりダーティな状態なページは開放できないものとみなされる。
- 閾値はハイページ/ローページ/最小限ページ。
- 最小限ページに達すると、ページアウトデーモンは同期モードになる
- ページを要求されるとそのタイミングでページを開放するようになる
- 最小限ページはチューニング可能。この2倍値・3倍値がローページ/ハイページになる
- 非アクティブ/アクティブなメモリそれぞれのLRUページリストをスキャンする
- 数秒以上もページスキャンがおこなわれるようなときは、一般的にメモリが圧迫されている兆候。
- Solarisの場合は、継続的ループによりすべてのメモリページをふたつのポインタ(フロントハンド/バックハンド)でメモリをスキャンするようにたどる。
- フリーリストに含まれる利用可能メインメモリが閾値未満になった際に、ページアウトデーモンによっておこなわれるもの
7.3.3 プロセスのアドレス空間
- アドレスは以下のような領域(セグメント)に分類される。
- スレッドのスタック
- プロセスの実行可能部
- ライブラリを格納するセグメント
- ライブラリのテキストセグメントは、同じライブラリをつかう他のプロセスと共有される。
- ライブラリのデータセグメントは、各プロセスがプライベートコピーを持つ。
- ヒープを格納するセグメント
- セグメントタイプ
- ヒープの成長
- アロケータ
- メモリのアロケーションには、ユーザーレベルとカーネルレベルとでさまざまなアロケータがある
- アロケータには、ばらばらになってしまっている未使用領域(フラグメンテーション)をまとめ、大きなメモリアロケーションでもそれを使えるようにしてくれたり、APIや可観測性を提供してくれたりしている
- スラブアロケータ
7.4 メソドロジ
7.4.1 ツールメソッド
調査対象がメモリの場合、ツールメソッドでチェックできるものは以下のような点。
- ページスキャン
- 継続的なページスキャンを探す。
sar -B
を実行した結果のpgscan
欄
$ sar -B Linux 3.10.0-327.10.1.el7.x86_64 (a-know-host) 2017年07月09日 _x86_64_ (1 CPU) 00時00分01秒 pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/s pgscand/s pgsteal/s %vmeff 00時10分01秒 20.49 4.82 404.74 0.12 171.76 11.04 0.28 6.11 53.97 00時20分01秒 11.67 14.00 392.53 0.08 171.96 13.01 1.79 8.40 56.76 00時30分01秒 6.21 3.40 403.32 0.07 170.68 0.00 0.00 0.00 0.00 00時40分01秒 7.47 7.24 1070.51 0.02 397.90 0.00 0.07 0.07 95.00 00時50分02秒 1.79 8.92 1319.62 0.02 488.73 0.00 0.00 0.00 0.00 01時00分01秒 0.41 8.53 1284.70 0.01 473.96 0.00 2.34 0.91 38.89
- ページング
vmstat(8)
を実行し、si, so欄をチェックする。vmstat
では、無名ページングを指してスワッピングという言葉が使われている
- 利用可能メモリ
vmstat
を1秒ごとに実行し、free欄をチェックする。
$ vmstat procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 55 0 189624 70624 0 136820 22 13 173 18 4 2 1 0 98 0 0
- OOMキラー
- 発生した際には
/var/log/messages
にメッセージが出力される
- 発生した際には
- スワッピング(Solarisのみ)
- スワッピングが発生すると事後にその事実が通知される
- 物理メモリ/仮想メモリを最も多く使っているプロセスの調査
top
prstat
- メモリが使われている理由の確認
7.4.2 USEメソッド
システム全体で以下のような点をチェックする(まずは飽和からチェックする)。
- 使用率
- どれだけのメモリが使われていて、どれだけのメモリが使用可能な状態か。
- 物理メモリとかそうメモリの両方をチェックする
- 飽和
- ページスキャン、ページング、スワッピング、それぞれの度合いを確認する
- OOMキラーの発生有無・それにより終了させられたプロセスのパフォーマンスを確認する
- エラー
- メモリアロケーションの失敗について確認する
7.4.3 使用形態の特性の把握
メモリをどこでどのように使っているかをはっきりさせる。
メモリの使用形態をもっと詳細に理解するためのチェックリストが以下。
- カーネルメモリはどこで使われているか。スラブアロケータ経由か。
- ファイルシステムキャッシュ(ページキャッシュ)のどれくらいの部分がアクティブで、どれくらいの部分が非アクティブか。
- プロセスのメモリはどこで使われているか。
- プロセスがメモリをアロケートしている理由は何か。
- カーネルがメモリをアロケートしている理由は何か。
- 活発にページアウト/スワップアウトされているプロセスはどれか。
- 以前にページアウト/スワップアウトされたことのあるプロセスはどれか。
- プロセスかカーネルにメモリリークはあるか。
- NUMAシステムにおいて、メモリはメモリノード全体にどれくらいうまく分散されているか。
- CPIとメモリストールサイクルの発生頻度はどうなっているか。
- メモリバスはどれくらいバランスが取れているか。
- リモートメモリI/Oに対するローカルメモリI/Oの比率はどれくらいになっているか。
7.4.4 サイクル分析
- メモリバスの負荷はCPCを見ることで調べられる
- CPCは、メモリストールサイクルを数えるようにプログラムすることができる
7.4.5 パフォーマンスモニタリング
今まさに発生している問題や経時的なふるまいを明らかにするためにパフォーマンスモニタリングは有用。
- 使用率:使われているメモリの割合。利用可能メモリから推論できる場合がある
- 飽和:ページング、スワッピング、OOMキラー
7.4.6 リーク検出
アプリケーションやカーネルモジュールのメモリ使用量が延々と増えていく現象。以下のどちらかが原因となっている
- メモリリーク
- メモリが使われていないのに開放されないというバグの一種
- メモリの成長
- ソフトウェアのメモリ消費としては正常だが、システムにとって望ましいペースよりもはるかに早いペースで増えているような状況。間違ってメモリリークと考えられてしまうこともある
7.4.7 静的パフォーマンスチューニング
- メインメモリは合計でどれだけあるか。
- アプリケーションはどれくらいメモリを消費するように構成されているか。
- アプリケーションはどのメモリアロケータを使っているか。
- メインメモリのスピードはどうなっているか。
- システムのアーキテクチャはどうなっているか(NUMA/UMA)
- オペレーティングシステムはNUMA対応か。
- メモリバスは何本あるか。
- CPUキャッシュの数とサイズはどうなっているか。TLBはどうか。
- 大きなページを構成しているか、使っているか。
- オーバーコミットは使えるか、構成されているか。
- システムメモリに関連するチューニングパラメータでほかに使われているものはなにか。
- ソフトウェアによって課されたメモリ制限はあるか。
7.4.8 リソースコントロール
OSは、プロセスやプロセスのグループにメモリをアロケーションするときに、きめ細やかなコントロールをすることができる。
7.4.9 マイクロベンチマーキング
7.5 分析
7.5.1 vmstat
- 仮想メモリ統計コマンド
- 現在のフリーメモリ、ページングについての統計などが取れる
$ vmstat procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 1 0 366624 74032 0 116636 21 13 172 18 0 3 1 0 98 0 0
-S
オプションで単位を変更
$ vmstat -Sm procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 2 0 375 71 0 122 0 0 172 18 0 3 1 0 98 0 0
-a
オプションで、ページキャッシュを非アクティブメモリとアクティブメモリに分割して表示。
$ vmstat -a procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free inact active si so bi bo in cs us sy id wa st 2 0 359280 63568 414280 424520 21 13 172 18 0 3 1 0 98 0 0
- swpd : スワップアウトされたメモリの容量
- free : 空きメモリ容量
- これがブート後にどんどんと減っていくことは正常なこと。それによりシステム全体のパフォーマンスを向上させている
- buff : バッファキャッシュ内のメモリ容量
- cache : ページキャッシュ内のメモリ容量
- si : スワップイン(ページング)されたメモリの容量
- so : スワップアウト(ページング)されたメモリの容量
- si, so の両方が継続的に0以外の値のときは、システムメモリが圧迫されているということ。
7.5.2 sar
- System Activity Reporter
- 現在のアクティビティを観察したり、統計の履歴情報をアーカイブし報告させたりできる
$ sar Linux 3.10.0-327.10.1.el7.x86_64 (a-know-host) 2017年07月15日 _x86_64_ (1 CPU) 00時00分01秒 CPU %user %nice %system %iowait %steal %idle 00時10分01秒 all 0.99 0.00 0.39 0.05 0.05 98.52 00時20分01秒 all 1.16 0.00 0.42 0.08 0.06 98.28 00時30分01秒 all 1.16 0.00 0.36 0.05 0.05 98.37 00時40分01秒 all 1.14 0.00 0.41 0.07 0.05 98.33 00時50分01秒 all 1.05 0.00 0.39 0.07 0.04 98.44
以下のようなオプションがサポートされている。
-B
: ページング統計-H
: ヒュージページ統計-r
: メモリの使用率-R
: メモリの統計-S
: スワップスペース統計-W
: スワッピング統計
$ sar -B Linux 3.10.0-327.10.1.el7.x86_64 (a-know-host) 2017年07月15日 _x86_64_ (1 CPU) 00時00分01秒 pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/s pgscand/s pgsteal/s %vmeff 00時10分01秒 85.03 7.04 411.95 0.74 200.87 28.96 8.85 19.56 51.74 00時20分01秒 176.28 10.17 426.64 0.73 221.91 67.84 0.00 40.83 60.19 00時30分01秒 22.17 5.76 405.47 0.72 181.86 21.25 0.00 10.96 51.57 00時40分01秒 186.21 12.47 399.26 0.64 223.42 69.13 6.64 47.50 62.69 00時50分01秒 159.11 11.64 412.64 0.52 211.58 56.44 0.26 38.49 67.89
%vmeff
はページ回収に関する統計。非アクティブリストからのページのスティールがうまくいっているかどうかの指標。高ければ高いほど効率よくおこなえていて、30%未満だと気をつける必要がある。
$ sar -r Linux 3.10.0-327.10.1.el7.x86_64 (a-know-host) 2017年07月15日 _x86_64_ (1 CPU) 00時00分01秒 kbmemfree kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact kbdirty 00時10分01秒 70796 944676 93.03 0 60608 1489196 47.84 419496 414012 8 00時20分01秒 63248 952224 93.77 0 70788 1490224 47.88 415840 425096 4 00時30分01秒 73216 942256 92.79 0 54884 1492668 47.96 420004 410296 4 00時40分01秒 72728 942744 92.84 0 59156 1489452 47.85 419544 411512 4 00時50分01秒 69388 946084 93.17 0 68080 1489452 47.85 424960 409296 8
7.5.3 slabtop
- スラブアロケータによるカーネルスラブキャッシュの使用状況を表示する
$ sudo slabtop -sc Active / Total Objects (% used) : 566810 / 616101 (92.0%) Active / Total Slabs (% used) : 8509 / 8509 (100.0%) Active / Total Caches (% used) : 64 / 95 (67.4%) Active / Total Size (% used) : 53240.84K / 66513.17K (80.0%) Minimum / Average / Maximum Object : 0.01K / 0.11K / 8.00K OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME 14336 12471 86% 0.57K 512 28 8192K radix_tree_node 10935 9817 89% 0.58K 405 27 6480K inode_cache 3128 2436 77% 1.88K 184 17 5888K TCP 5460 1262 23% 1.06K 182 30 5824K xfs_inode 73792 56753 76% 0.06K 1153 64 4612K kmalloc-64 21987 16426 74% 0.19K 1047 21 4188K dentry
- 出力上部は集計
- 出力下部
- OBJS : オブジェクト数
- ACTIVE : アクティブオブジェクト数
- USE : 使用率
- OBJ SIZE : オブジェクトサイズ
- CACHE SIZE : キャッシュの合計サイズ
7.5.4 ::kmastat
7.5.5 ps
- すべてのプロセスの詳細情報を表示する
$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.3 191164 3572 ? Ss 3月18 8:26 /usr/lib/systemd/systemd --system --deserialize 22 root 2 0.0 0.0 0 0 ? S 3月18 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? S 3月18 0:02 [ksoftirqd/0] root 7 0.0 0.0 0 0 ? S 3月18 0:00 [migration/0]
7.5.6 top
- 各プロセスのCPU消費状況をモニタリングするものだが、メモリの使用状況についての統計も含まれている
- 4,5行目。
top - 09:55:23 up 119 days, 40 min, 2 users, load average: 0.01, 0.03, 0.07 Tasks: 117 total, 2 running, 115 sleeping, 0 stopped, 0 zombie %Cpu(s): 1.0 us, 0.4 sy, 0.0 ni, 98.4 id, 0.1 wa, 0.0 hi, 0.0 si, 0.1 st KiB Mem : 1015472 total, 71092 free, 812280 used, 132100 buff/cache KiB Swap: 2097148 total, 1722904 free, 374244 used. 60912 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 21967 a-know 20 0 157700 2160 1500 R 6.7 0.2 0:00.01 top 1 root 20 0 191164 3572 2240 S 0.0 0.4 8:26.03 systemd
7.5.7 prstat
- Solaris ベースシステム用の top
7.5.8 pmap
$ sudo pmap -x 26288 26288: /opt/td-agent/embedded/bin/ruby /usr/sbin/td-agent --log /var/log/td-agent/td-agent.log --use-v1-config --group td-agent --daemon /var/run/td-agent/td-agent.pid Address Kbytes RSS Dirty Mode Mapping 0000000000400000 4 0 0 r-x-- ruby 0000000000600000 4 0 0 r---- ruby 0000000000601000 4 0 0 rw--- ruby 00007f2d24dfe000 4 0 0 ----- [ anon ] 00007f2d24dff000 1024 4 4 rw--- [ anon ] 00007f2d24eff000 4 0 0 ----- [ anon ] [...] ---------------- ------- ------- ------- total kB 1024936 188860 184672
- Kbytes : 仮想メモリ
- RSS : メインメモリ
- Dirty : プライベート無名メモリ
- Mode : パーミッション
- 読み出し専用
r-x
のものは他プロセスと共有できるもの、ということ。
- 読み出し専用
- pmap はメモリの使用状況を表示するときにプロセスを一時停止するので、アクティブな作業パフォーマンスを損ねることがあるので、常時実行することは避ける。
7.5.9 DTrace
7.5.10 SystemTap
- ファイルシステムイベントの動的トレーシングをおこなうためのツール
7.5.11 その他のツール
- free : バッファキャッシュやページキャッシュも含めて、フリーメモリを返す
$ free total used free shared buff/cache available Mem: 1015472 823740 63780 900 127952 51512 Swap: 2097148 376304 1720844
- dmesg : OOMキラーが出力した「Out of memory」メッセージをチェックする。
- valgrind : パフォーマンス分析スイート。リーク検出を含むメモリの使用状況分析用のユーザーレベルアロケータラッパー(
memcheck
)が含まれる - swapon : 物理スワップデバイス・ファイルを追加し、観察する
- iostat : スワップデバイスが物理ディスクやディスクスライスの場合、そのデバイスI/Oを観察するために利用可能。デバイスI/Oはシステムがページングしていることを示す。
$ iostat Linux 3.10.0-327.10.1.el7.x86_64 (a-know-host) 2017年07月15日 _x86_64_ (1 CPU) avg-cpu: %user %nice %system %iowait %steal %idle 1.01 0.00 0.38 0.11 0.05 98.45 Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn xvda 5.68 172.23 17.53 1686628728 171623891
- perf : CPUパフォーマンスインストルメンテーションカウンタから、CPI, MMU/TLB イベント、メモリバスストールサイクルを調査することができる
- proc/zoneinfo : メモリゾーンの統計(NUMAノード)
$ cat /proc/zoneinfo Node 0, zone DMA pages free 1206 min 176 low 220 high 264 scanned 0 spanned 4095 present 3997 managed 3976 nr_free_pages 1206 nr_alloc_batch 44 nr_inactive_anon 1193 nr_active_anon 1157 nr_inactive_file 101
- proc/buddyinfo : カーネルバディアロケータの統計
$ cat /proc/buddyinfo Node 0, zone DMA 12 19 12 18 24 6 0 1 1 0 0 Node 0, zone DMA32 538 693 275 200 87 92 36 11 5 2 0
7.6 チューニング
- メモリのチューニングでもっとも大切なのは、アプリケーションがメインメモリに残るようにすることとともに、ページングやスワッピングが頻繁に発生しないようにすること。
- この節では、以下のような項目について確認する
7.6.1 チューニング可能なパラメータ
- Documentation/sysctl/vm.txt にメモリ関連のさまざまなチューニング可能パラメータのことが書かれている
sysctl(8)
で設定できる*_bytes
と*_ratio
はどちらか片方だけしか設定できない。
7.6.2 複数のページサイズ
- ページサイズを大きくすると、TLBのキャッシュヒット率が上がり、メモリI/Oのパフォーマンスが上がる。
- 最近のプロセッサのほとんどは、4kb/2MB のような形で複数のページサイズをサポートしている
- ヒュージページと呼ばれる大きなページは、複数の方法で構成できる
- Documentation/vm/hugetlbpage.txt
- 最近では、透過的なヒュージページのサポートも開発されている
- 手作業による設定の必要なく、適切なときにヒュージページを使うようにできるもの
- Documentation/vm/transhuge.txt
7.6.3 アロケータ
7.6.4 リソースコントロール
- Linux だとコンテナグループ(
cgroup
)
7.7 練習問題
メモリの用語について
- 「ページ」
- OSとCPUが使うメモリの単位。伝統的に4kbや8kbが用いられる。
- 常駐メモリ
- 現在メインメモリにあるメモリ。
- 非常駐メモリにアクセスが発生した場合、ディスクデバイス等からのデータの読み込みが発生する。
- 仮想メモリ
- メインメモリの抽象。実メモリではない。
- Unix用語におけるページングとスワッピングの違い
- Linux用語におけるページングとスワッピングの違い
コンセプトについて
- デマンドページングの目的
- 該当アドレスのメモリ内容が必要となった時点で、物理ページを論理ページに割り当てることで、CPUにかかるマッピング作成のオーバーヘッドを先延ばしにすることができる。
- メモリの使用率と飽和とは
- 使用率:使われているメモリの割合。通常、ページキャッシュやバッファの使用率は含めない。
- 飽和:利用可能メモリが無くなった状態。ページスキャン、ページング、スワッピング、OOMキラーなどの発生頻度が上がる
- MMU と TLB の目的
- MMU : 仮想メモリアドレスを物理アドレスに変換する際に必要なもの
- TLB : アドレス変換キャッシュ。
- MMUはL1キャッシュ(CPUキャッシュ)とL2キャッシュの間に位置する
- CPUからL1キャッシュは、仮想アドレスで直接アクセスする
- L2キャッシュへのアクセスの際には、MMUでアドレス変換をおこなったのちに物理アドレスでアクセスをおこなう
- アドレス変換の際、ページテーブルを参照する前にTLB(Translation Lookaside Buffer)をアドレス変換キャッシュとして用いる。
- TLBにヒットしなかった場合は、メインメモリ上のページテーブルにアクセスしてアドレス変換をおこなう。
- ページアウトデーモンの役割
- フリーリストに含まれる利用可能メインメモリが閾値未満になった際に、ページスキャンをおこなう
- 最近使われていないページ(アプリケーションメモリも含む)を見つけてきてフリーリストに追加する
- ページアウトデーモンはまず非アクティブリストをスキャンしてから、その後必要ならばアクティブリストをスキャンする
- 最小限ページに達すると、ページアウトデーモンは同期モードになる
- ページを要求されるとそのタイミングでページを開放するようになる
- フリーリストに含まれる利用可能メインメモリが閾値未満になった際に、ページスキャンをおこなう
- OOMキラーの役割
- メモリ枯渇時にOOMキラーによってプロセスを強制終了させることで、メモリの確保を図る