SystemTapで真犯人を捕まえろ!Linuxトラブルシューティング探偵団 番外編(3)(1/4 ページ)

» 2009年03月25日 00時00分 公開
[高田哲生, 前野真輝NTT OSSセンタ]

 NTTグループの各社で鳴らした俺たちLinuxトラブルシューティング探偵団は、各社で培ったOSS関連技術を手に、NTT OSSセンタに集められた。普段は基本的にNTTグループのみを相手に活動しているが、それだけで終わる俺たちじゃあない。 

ソースコードさえあればどんなトラブルでも解決する命知らず、不可能を可能にし、多くのバグを粉砕する、俺たちLinuxトラブルシューティング探偵団! 助けを借りたいときは、いつでもいってくれ!

OS:高田哲生

俺はリーダー、高田哲生。Linuxの達人。俺のようにソースコードレベルでOSを理解している人間でなければ、百戦錬磨のLinuxトラブルシューティング探偵団のリーダーは務まらん。

Web:福山義仁

俺は、福山義仁。Web技術の達人さ。ApacheのようなWebサーバからTomcat、JBossみたいなJava、アプリケーション技術まで、何でも問題を解決してみせるぜ。

DBMS:下垣徹

下垣徹。PostgreSQLの達人だ。開発からサポートまで何でもやってみせらぁ。でも某商用DBMSだけは勘弁な。

HA:田中 崇幸

よぉ! お待ちどう。俺さまこそHAエキスパート。Heartbeatを使ってクラスタを構成する腕は天下一品! HAが好きなんて奇人? 変人? だから何? HaHaHaHa!!

 番外編もついに最終回! Linuxトラブルシューティング探偵団の活躍もひとまずの終了を迎えるぜ! 最後はメモリ不足騒動の顛末(てんまつ)。さらにOSの奥深くへ踏み込んだ内容になっていくが、最後までついてきてくれ!

関連記事:

連載記事 「Linuxトラブルシューティング探偵団」

http://www.atmarkit.co.jp/flinux/index/indexfiles/tsindex.html


/proc/meminfoで物理メモリの詳細な利用状況を把握

 前回までで「カーネル空間」の「物理メモリ」を消費し過ぎた結果、OS停止に至った可能性があるというところまで突き止めました。今回は、カーネル空間のどの部分を消費し過ぎていたのか、さらには根本的な原因は何だったのかを追求していきます。

 カーネル空間の物理メモリといっても、まずはどの部分のメモリを消費しているのか把握しなければなりません。これを把握するには/proc/meminfoを見るのが最も簡単です。/proc/meminfoの出力例は以下のようなものでした。

MemTotal: 2073208 kB
MemFree: 1388360 kB
Buffers: 57096 kB
Cached: 317824 kB
SwapCached: 0 kB
Active: 469980 kB
Inactive: 168980 kB
HighTotal: 1178048 kB
HighFree: 590592 kB
LowTotal: 895160 kB
LowFree: 797768 kB
SwapTotal: 2096472 kB
SwapFree: 2096472 kB
Dirty: 8992 kB
Writeback: 0 kB
Mapped: 322512 kB
Slab: 27932 kB
CommitLimit: 3133076 kB
Committed_AS: 585468 kB
PageTables: 3840 kB
VmallocTotal: 106488 kB
VmallocUsed: 2908 kB
VmallocChunk: 103500 kB
HugePages_Total: 0
HugePages_Free: 0
Hugepagesize: 2048 kB

 上記の値については、原則として以下のような計算式が成り立ちます。

MemTotal=MemFree+Active+Inactive+Slab+

        VmallocUsed(※)+PageTables

メモリ使用量を求める式(1)

 今回重要なのは、この式(1)です。式(1)を図示すると図1のようになります。

図1 メモリマッピング 図1 メモリマッピング

 第1回で説明したとおり、InactiveとMemFreeを足したものが利用可能なメモリです。第1回で説明していないVmallocUsed、Slab、PageTablesはカーネル内で確保する領域です。これらについてもう少しだけ詳しく説明しておきます。

 VmallocUsed)は、カーネル内のvmalloc()というAPI経由で確保されるメモリを想定しています。この領域は、ドライバなどのカーネルモジュールによって確保されることが多く、システムがいったん起動してしまうとあまり増減しません。ただ、x86_64でMMCONFIG(注1)を利用している場合、カーネル内の仮想メモリを256MiB(注2)予約しており、/proc/meminfoのVmallocUsedにはこの値が足し込まれます。しかし実際は、よほどデバイス数が多くない限り、実際に使っているのは数Mbytes程度です。

 そこでこの際、MMCONFIG用に予約されている256MiBはVmallocUsedから引いてしまいましょう。具体的には256Mbytes=262144KbytesをVmallocUsedから引いたものを、上記式(1)のVmacllocUsed()として計上します。

 なお、MMCONFIGを使っているかどうかは下記のコマンドで確認できます。MMCONFIGを使っていなければ、VmallocUsedの値をそのまま使用してください。

# dmesg | grep MMCONFIG
PCI: Using MMCONFIG      ←これが出力されればMMCONFIGはONです

PCI: Not using MMCONFIG. ←これが出力されればMMCONFIGはOFFです

 Slabは、kmalloc()というAPIでメモリを確保する仕組みで、スラブアロケータという仕組みで管理されています。スラブアロケータはカーネル内のメモリプールで、メモリの断片化を防ぐ仕組みが入っており、確保/解放を繰り返すような使い方をするメモリに使われます。

関連記事:

Linuxメモリ管理の最先端を探る

http://www.atmarkit.co.jp/flinux/rensai/watch2008/watchmema.html


 PageTablesは、ページテーブルエントリという「ページ」の管理構造体として利用されているメモリです。ページとは、カーネル内におけるメモリの管理単位で、vmalloc()で確保したメモリにしろ、kmalloc()で確保したメモリにしろ、メモリは基本的にこの単位で割り当てられます。サイズは物理メモリ量に応じて決まり、一度システムが起動してしまえば変化しません。

 これらはカーネル内の領域なので、解放することはできません。Activeと併せて「解放不可能なメモリ」ということでまとめられます。

注1:Memory Mapped Configuration。デバイスへメモリを割り当てる設定方法の一種

注2:メビバイト。1MiB=2^20 Bytes=1,048,576Bytesとなり、1MBytes(=1000000Bytes)とは値が異なる。


コラム /proc/meminfo〜Linuxメモリの地図〜を把握しよう

 /proc/meminfoは第1回で出てきましたが、詳しく説明していませんでした。その出力が意味するところを説明してしまいましょう。

項目名 説明
MemTotal システム全体で利用できる物理メモリの総容量。システム起動時に計算される。その後、この値が変化することはない
MemFree システム全体で利用できる物理メモリの空き容量
Buffers ファイルなどのメタデータとして使用している物理メモリの総容量
Cached ファイルデータのキャッシュなどに使用している物理メモリの総容量。共有メモリは Cached に加算される。SwapCachedは含まない
SwapCached 物理メモリ上にキャッシュされたスワップページの総容量
Active 最近アクセスした(とカーネルが思っている)物理メモリの容量
Inactive 最近アクセスしていない(とカーネルが思っている)、解放してよい物理メモリの容量
HighTotal Highmem領域にある物理メモリの容量。x86アーキテクチャ(32bit)にのみ存在し、通常、896Mbytesを超える物理メモリはこの領域で扱われる
HighFree Highmem領域にある物理メモリの空き容量。x86アーキテクチャ(32bit)のみ存在
LowTotal Lowmem領域にある物理メモリの容量(MemTotal-HighTotal)の値。x86アーキテクチャ(32bit)の場合、0xc0000000〜0xf8000000の間の896MBytesの範囲。x86_64アーキテクチャ(64bit)の場合、すべてのメモリがLowmem領域で扱われる
LowFree Lowmem領域にある物理メモリの空き容量。(MemFree-HighFree)の値
SwapTotal スワップ領域の総容量。使用/未使用にかかわらずすべてのパーティション/ファイルのスワップ領域が含まれる。swapon/swapoffコマンドによるスワップ領域の増減も反映される
SwapFree スワップ領域の空き容量。使用しているすべてのスワップ領域の空きと未使用のすべてのスワップ領域が含まれる
Dirty ディスクとの同期が取れていない物理メモリの総容量
Writeback ディスクへ書き出し中の物理メモリの総容量
Mapped ページテーブルに登録されている物理メモリの総容量。ページキャッシュと無名ページの両方が含まれる。最近のカーネルでは、AnonPagesとMappedに分離
Slab スラブアロケータで使用されている物理メモリの総容量
CommitLimit 仮想メモリを取得できるかどうかの判断に使われる閾値。
((vm.overcommit_ratio×物理メモリ量)+スワップ量)の値。vm.overcommit_memory=2のときにのみ使われる。vm.overcommit_memory=0 or 1のときにはまったく関係ない
Committed_AS 全プロセスによって確保された仮想メモリの総容量。vm.overcommit_memory=2のときにこの値がCommitLimitより大きいとメモリ不足と判定され、malloc()などが失敗する
PageTables ページテーブルエントリで使用されている物理メモリの容量
VmallocTotal vmalloc()で利用可能な仮想メモリ領域の容量。x86_64アーキテクチャの場合、定数
VmallocUsed vmalloc()で確保された物理メモリ領域とMMCONFIGで確保しているメモリ領域の総容量
VmallocChunk vmalloc()で確保された仮想メモリ領域のfree領域の中で最も大きい連続領域の容量
HugePages_Total hugepageとして確保された物理メモリの総量
HugePages_Free HugePages_Free
Hugepagesize Hugepagesize

Active+Inactive=AnonPages+Cached+Buffers+SwapCached

メモリ使用量を求める式(2)

 式(2)の中にあるAnonPagesとは、/proc/meminfoの出力内にはありませんが、無名ページ(Anonymous Page)の領域を表しています。無名ページとは、第2回でも少しだけ説明しましたが、ユーザープロセスがmalloc()などで確保したり、プログラム本体用に利用するメモリ領域です。

 出力例を見てもらえば分かりますが、AnonPagesは/proc/meminfoには出力されません。RHEL 5など最近のバージョンのカーネルには入っているのですが、RHEL 4時点ではこの値は存在しませんでした。従って、RHEL 4でAnonPagesを把握したい場合は、式(2)の計算式で求めることになります。


       1|2|3|4 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。