えいのうにっき

むかしのじぶんのために書いています

読書メモ・詳解システムパフォーマンス 第7章/メモリ

「詳解システムパフォーマンス」の読書メモシリーズ・第6弾。

詳解 システム・パフォーマンス

詳解 システム・パフォーマンス

感想

  • また一ヶ月も間隔が開いてしまった…。。
  • 引き続きおもしろい。いままで断片的に触れてきたところの穴埋めができたような感覚。
  • ただ難しさを感じるところ、なかなか頭に入ってこないところもある。
    • ex. スラブアロケータ、「無名xx」、リーピングとフリーリストの関係(関係ない?)
    • 微妙な表現とかニュアンスのせいなのかもしれないけど、結局何を指しているのかがわかりにくいからだったり、頭の中でうまく関連付けられてなかったりしてるんだろうなー。

読書メモ

7.1 用語

  • メインメモリ:物理メモリとも。一般に DRAM で提供される
  • 仮想メモリ:メインメモリの抽象。実メモリではない
  • 常駐メモリ:現在メインメモリにあるメモリ。
  • 無名メモリ:ファイルシステム位置やパス名を持たないメモリ。ヒープ(プロセスのアドレス空間内のワーキングデータ)を含む。
  • ページ:OSとCPUが使うメモリの単位。伝統的に4kbや8kbが用いられる。
  • ページフォルト:無効なメモリアクセス。オンデマンド仮想メモリを使うときには普通に発生する。
  • ページング:メインメモリとストレージデバイスの間でのページの転送。
  • スワッピング
  • スワップ:ページングされる無名データやスワップされるプロセスのうち、ディスク上の部分。物理スワップバイスであることもあれば、スワップファイルであることもある

7.2 コンセプト

7.2.1 仮想メモリ

7.2.2 ページング

  • 外部からメインメモリにページを移動することをページイン、メインメモリから外部に移動することをページアウトという。
  • ファイルシステムページング
    • ファイルシステムページのページングのための仕組み。メモリマップトファイルにページを読み書きする
  • 無名ページング
    • プロセスのプライベートデータ(ヒープとスタックのデータ)のページング。
    • かならず物理スワップバイススワップファイルへのデータの移動を必要とする
      • Linux ではこれを指してスワッピングと呼んでいる
    • 無名ページングはパフォーマンスを下げる。この発生がないときにパフォーマンスは最高になる
      • ページスキャン、メモリの使用率、無名ページングを監視しメモリ不足の兆候が起きないようにすることが重要

7.2.3 デマンドページング

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)レイテンシ
    • メモリモジュールに読み込みたいアドレス(column)を送ってから、データが読み出せる状態になるまでの時間。
    • モリタイプによって異なる。
    • 例えば64ビット幅のメモリバスが、64バイト幅分のキャッシュラインを転送するために、このレイテンシが複数回発生することがある。
    • 新しく利用可能になったデータを読み出すために、CPUとMMUでも別のレイテンシが発生することもある
  • メインメモリのアーキテクチャ
    • 複数プロセッサUMAの場合、各CPUは共有システムバスを介して全てのメモリに対して一定のアクセスレイテンシでアクセスすることができる
    • 複数プロセッサNUMAの場合、メインメモリに対するアクセス時間はCPUからの相対的な距離によって変わる。
      • 別のCPUのインターコネクトを介してI/Oを実行する必要があるようなメモリのことをリモートメモリ、直接アクセスできる位置にあるメモリのことをローカルメモリと呼ぶ。
    • メモリノード:個々のCPUに接続されているメモリのバンクのこと。
      • OSは、プロセッサから得られる情報にもとづき、メモリノードのトポロジを意識し、出来る限りローカルメモリを使うようにする(メモリの局所性を尊重する)ようなメモリの配置をおこなう場合がある。
  • バス
    • 共有システムバスUMAなどのような、各CPUと各メモリとが共通のシステムバスで接続されているようなタイプ。
    • ダイレクト:シングルプロセッサとメモリをメモリバスで直接結ぶ形式。
    • インターコネクト:マルチプロセッサの各プロセッサがメモリバスを介して各メモリと直接接続され、また各CPU同士もCPUインターコネクトを介して接続されているタイプ。
  • DDR SDRAM
    • Double Data Rate Synchronous Dynamic Random-Access Memory
    • Double Data Rate:クロックシグナルのライズエッジとフォールエッジの両方でデータを転送すること。
    • Synchronous:メモリのクロックがCPUのクロックと同期していること。
  • マルチチャンネル
    • 帯域幅の向上のため、複数のメモリバスを並列的に利用すること
  • CPUキャッシュ
    • レベル1 -> レベル3 となるにつれ、サイズは大きくなるがスピードは遅くなる
    • レベル1は一般に仮想メモリアドレスで参照されるのに対し、レベル2は物理アドレスで参照されることが多い。
  • MMU
    • Memory Management Unit
    • 仮想アドレスから物理アドレスへの変換を行なう
    • 変換はページ単位、ページ内オフセットは直接マッピング
    • L1キャッシュ(CPUキャッシュ)とL2キャッシュの間に位置する
      • CPUからL1キャッシュは、仮想アドレスで直接アクセスする
      • L2キャッシュへのアクセスの際には、MMUでアドレス変換をおこなったのちに物理アドレスでアクセスをおこなう
        • アドレス変換の際、ページテーブルを参照する前にTLB(Translation Lookaside Buffer)をアドレス変換キャッシュとして用いる。
        • TLBにヒットしなかった場合は、メインメモリ上のページテーブルにアクセスしてアドレス変換をおこなう。
  • 複数のページサイズ
    • 最近のプロセッサは、複数ページサイズをサポートしている。なのでOSとMMUは、異なるページサイズを扱うことができる
    • ヒュージページ:Linuxにある機能。2MBなどの大きなページサイズで使うために物理メモリの一部を残しておくもの。
  • TLB
    • アドレス変換用のキャッシュ。
    • 命令ページとデータページのために別々のキャッシュに分割できる
    • TLBが持つマッピングエントリ数には限りがある
      • 大きなページサイズを使うことでキャッシュで翻訳できるメモリの範囲が広がり、TLBミスが減りシステムのパフォーマンスが上がる。

7.3.2 ソフトウェア

  • メモリの開放
    • フリーリスト:すぐにアロケーションに回せる未使用ページのリスト。通常は、ローカリティグループ(NUMA)ごとにひとつずつのフリーページリストとして実装されている
    • リーピング:メモリ枯渇の閾値を越えたとき、簡単に開放できるメモリを即刻開放させるための命令。カーネルモジュールとカーネルスラブアロケータが対象。
    • ページキャッシュ:ファイルシステムキャッシュ。swappiness パラメータによって、スワッピングの実施ではなくページキャッシュからのメモリ解放の選択を優先する度合いを指定することもできる。
    • スワッピング:kswapd(ページアウトデーモン)によるページング。最近使われていないページ(アプリケーションメモリも含む)を見つけてきてフリーリストに追加する。その後ページアウトされ、その結果としてスワップファイルかスワップバイスへの書き込みを伴うこともある。
      • スワップファイルかデバイスが構成されているときに限りおこなわれる。これらが構成されていないときは即座にOOMキラーに強制終了されることになり、ページングという緩衝手段が使えない。
    • OOMキラー:select_bad_process() で見つけたプロセスを強制終了することでメモリを開放する。 その際には /var/log/messages 内に Out of memory: Kill process というメッセージとして出力もされる。
    • Solaris では、ページングが発生するときはシステムキャッシュが空のときである一方で、Linux の場合は swappiness パラメータによりコントロールすることができる。
      • コールドなアプリケーションメモリをページアウトしつつ、ウォーム状態のファイルシステムキャッシュを温存することによって、システムのスループットを向上させることが可能。
  • フリーリスト
    • 利用可能メモリをすぐに見つけられるようにするもの。
    • 明示的に開放されたメモリは、今後のアロケーションで使えるようにリストの先頭に追加される
    • 明示的な開放ではなく、ページアウトデーモンによって開放されたメモリはリストの末尾に追加される
      • キャッシュされたファイルシステムページとしてまだ使える情報情報が含まれているため
      • アロケートされ再利用されるまえにそのページに対するアクセスがあると、そのページはフリーリストからは削除されてキャッシュとして復活する
    • バディアロケータ:Linuxにおいてページを管理するために使用されているアロケータ
      • ページの近隣のフリーメモリを見つけて、それらをいっしょにアロケートできることから バディ とされている
      • さまざまなサイズのメモリアロケーションのために複数のフリーリストを管理している
  • リーピング
    • カーネルのスラブアロケータキャッシュからメモリを開放すること
      • スラブアロケータキャッシュには、すぐに再利用可能なスラブサイズの未使用メモリ(チャンク)が含まれている
  • ページスキャン
    • フリーリストに含まれる利用可能メインメモリが閾値未満になった際に、ページアウトデーモンによっておこなわれるもの
      • 非アクティブ/アクティブなメモリそれぞれのLRUページリストをスキャンする
        • ページアウトデーモンはまず非アクティブリストをスキャンしてから、その後必要ならばアクティブリストをスキャンする
        • ロックされていたりダーティな状態なページは開放できないものとみなされる。
      • 閾値はハイページ/ローページ/最小限ページ。
      • 最小限ページに達すると、ページアウトデーモンは同期モードになる
        • ページを要求されるとそのタイミングでページを開放するようになる
      • 最小限ページはチューニング可能。この2倍値・3倍値がローページ/ハイページになる
    • 数秒以上もページスキャンがおこなわれるようなときは、一般的にメモリが圧迫されている兆候。
    • Solarisの場合は、継続的ループによりすべてのメモリページをふたつのポインタ(フロントハンド/バックハンド)でメモリをスキャンするようにたどる。

7.3.3 プロセスのアドレス空間

  • アドレスは以下のような領域(セグメント)に分類される。
    • スレッドのスタック
    • プロセスの実行可能部
    • ライブラリを格納するセグメント
      • ライブラリのテキストセグメントは、同じライブラリをつかう他のプロセスと共有される。
      • ライブラリのデータセグメントは、各プロセスがプライベートコピーを持つ。
    • ヒープを格納するセグメント
  • セグメントタイプ
    • 実行可能テキスト:プロセスのための実行可能CPU命令を収めている/ファイルシステム上のバイナリプログラムのテキストセグメントからマッピングされている/読み出し専用で実行可能パーミッション
    • 実行可能データ:バイナリプログラムのデータセグメントからマッピングされた初期化済み変数を収めている/読み書き両用パーミッション/変更はディスクにフラッシュされない
    • ヒープ:プログラムのワーキングメモリ。無名メモリ(ファイルシステム上の位置を持たない)。
    • スタック:実行中スレッドのスタック/読み書き両用
  • ヒープの成長
    • ほとんどのアロケータでは free() はOSにメモリをすぐには返さず、将来のアロケーションのためにすぐに使えるようにキープしている
    • そのため、プロセスの常駐メモリは増える一方であり、それが正常な動作である
    • exec() を呼び出すことで空のアドレス空間から実行が開始される(再実行)ことを利用したり、mmap()munmap() を使うことでシステムにメモリを返却することができる
  • アロケータ
  • スラブアロケータ
    • 確保しようとするオブジェクトのサイズに合ったサイズで確保されるので、メモリの使用効率が高い。
      • 特定サイズ(固定)のオブジェクトのキャッシュを管理し、ページアロケーションのオーバーヘッドをかけずに高速に再利用できるようにしてくれている
    • Linux のスラブアロケータは、従来までのスラブアロケータよりも改善されている
      • オブジェクトキューの削除/CPUごとのキャッシュの削除/NUMAの最適化の放棄(ページアロケータへの委譲)

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

  • Solaris ベースのシステムでは、 mdb(1) の ::kmstat デバッガコマンドでカーネルメモリの使用状況の概要を得られる

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]
  • %MEM : メインメモリの使用状況。システム内のメモリの総合計に対する割合として表示
  • RSS : メインメモリの使用状況・常駐セットサイズ
    • 他プロセスにもマッピングされている可能性のあるシステムライブラリなどの共有セグメントを含む。
    • そのため、RSS 欄の合計=システム内メモリの総合計、とは必ずしもならない。
  • VSZ : 仮想メモリサイズ

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キラーによってプロセスを強制終了させることで、メモリの確保を図る

その他

  • 無名ページングとは何か。ファイルシステムページングよりもこちらの分析が重要なのはなぜか。
    • プロセスのプライベートデータ(ヒープとスタックのデータ)のページングのこと。
    • ファイルシステムページングとくらべて、無名ページングは発生すると 物理スワップバイススワップファイルへの書き込み(Linuxでいうスワッピング)が必ず発生する ため、パフォーマンス分析の際にはこちらの分析の方が重要。
  • フリーメモリが不足したときに、メモリを広げるために Linux カーネルが取る手順はどんなものか。
    • リーピング・ページキャッシュの開放・ページアウトデーモンによるページスキャン・フリーリストへの追加・ページング・スワッピング
    • OOMキラー
  • スラブベースのアロケーションのパフォーマンス上の利点はなにか。
    • 確保しようとするオブジェクトのサイズに合ったサイズで確保されるので、メモリの使用効率が高い。


follow us in feedly