Valgrindはメモリ管理のデバッグとプロファイリングのためのツールを提供するフレームワーク。 多くのLinuxやUnixをサポートしている。
このエントリではValgrindが提供するMassifというツールを使用して、あるプログラムのメモリ使用量をプロファイリングしてみる。
Debianならvalgrind
パッケージをインストールすればValgrindが使用できるようになる。
apt-get install valgrind
プログラムはRubyで巨大なYAMLファイルを少しずつ読み込んで処理するで作成したload_documents.rb
とload_stream.rb
を使用する。
-
load_documents.rb
– 巨大ファイルの全内容を読み込んで処理するスクリプト(メモリ使用量大) -
load_stream.rb
– 巨大ファイルの少しずつ読み込んで処理するスクリプト(メモリ使用量小)
Massifを実行するには以下のようにする。 Massif経由でプログラムを実行するとプロファイリングのため非常に遅くなるので注意が必要。
valgrind --tool=massif 測定対象のプログラム
実行するとmassif.out.pid
というファイルが出力される。 pid
の部分にはプロセスIDが入る。
このファイルにプロファイリング結果が保存されているので、Valgrindのms_print
というコマンドで内容を表示する。 ms_print
の出力は膨大なので、実際にはless
などのページャで読むと良い。
ms_print massif.out.pid
出力の冒頭にグラフが表示されている。 これで時系列でメモリ使用量がわかる。
以下はload_documents.rb
のグラフ。 メモリを34MB使用している。 処理前にファイルの内容を全て読み込むため、最初の方でメモリ使用量が急増する様子がわかる。
--------------------------------------------------------------------------------
Command: ruby load_documents.rb
Massif arguments: (none)
ms_print arguments: massif.out.8336
--------------------------------------------------------------------------------
MB
34.19^ #
| #
| @#
| @@#
| @@@#
| @@@@#
| ::::::@:::::::::@@:::::::::::: @@@@@#
| ::@@::::::::::::::: :@:: ::: ::@ : :::: :: :::::::::::::@@@@@#
| :: @ :: :: :: : :::: :@:: ::: ::@ : :::: :: :::::::::: ::@@@@@#
| @@:: @ :: :: :: : :::: :@:: ::: ::@ : :::: :: :::::::::: ::@@@@@#
| @@ :: @ :: :: :: : :::: :@:: ::: ::@ : :::: :: :::::::::: ::@@@@@#
| @@@ :: @ :: :: :: : :::: :@:: ::: ::@ : :::: :: :::::::::: ::@@@@@#
| @@@ :: @ :: :: :: : :::: :@:: ::: ::@ : :::: :: :::::::::: ::@@@@@#
| @@@@@ :: @ :: :: :: : :::: :@:: ::: ::@ : :::: :: :::::::::: ::@@@@@#
| :@ @@@ :: @ :: :: :: : :::: :@:: ::: ::@ : :::: :: :::::::::: ::@@@@@#
| ::@ @@@ :: @ :: :: :: : :::: :@:: ::: ::@ : :::: :: :::::::::: ::@@@@@#
| ::@ @@@ :: @ :: :: :: : :::: :@:: ::: ::@ : :::: :: :::::::::: ::@@@@@#
| ::@ @@@ :: @ :: :: :: : :::: :@:: ::: ::@ : :::: :: :::::::::: ::@@@@@#
| ::@ @@@ :: @ :: :: :: : :::: :@:: ::: ::@ : :::: :: :::::::::: ::@@@@@#
| ::@ @@@ :: @ :: :: :: : :::: :@:: ::: ::@ : :::: :: :::::::::: ::@@@@@#
0 +----------------------------------------------------------------------->Gi
0 11.73
一方、以下はload_stream.rb
のグラフ。 メモリ使用量は約10MBと抑えられている。 こちらはメモリ使用量はほぼ一定であることがわかる。 ギザギザしているのはRubyのガベージコレクションだと思われる。
--------------------------------------------------------------------------------
Command: ruby load_stream.rb
Massif arguments: (none)
ms_print arguments: massif.out.8377
--------------------------------------------------------------------------------
MB
10.24^ :
| #:::: :::::: :@::::: :::::: ::::@ ::
| :#: :: : :::: :@: :: ::: ::: @::::@ @::
| :: @::#: :: :: :::: ::@: :: :::: ::: :@::::@ :@::
| ::: @::#: :: @:: :::: :::@: :: ::::: ::: ::@::::@ ::@::
| :::: ::@::#: :: :@:: :::: :::::@: :: ::::: ::: ::@::::@ :::@::
| @:::: :: @::#: :: ::@:: :::: : :::@: :: :::::: ::: ::::@::::@ ::::@::
| @::::::: @::#: :::::@:: :::: :: :::@: :: ::::::: :::@: ::@::::@:::::@::
| @::::::: @::#: :::::@:: ::::::: :::@: :: ::::::: :::@: ::@::::@:::::@::
| @::::::: @::#: :::::@:: ::::::: :::@: :: ::::::: :::@: ::@::::@:::::@::
| @::::::: @::#: :::::@:: ::::::: :::@: :: ::::::: :::@: ::@::::@:::::@::
| @::::::: @::#: :::::@:: ::::::: :::@: :: ::::::: :::@: ::@::::@:::::@::
| @::::::: @::#: :::::@:: ::::::: :::@: :: ::::::: :::@: ::@::::@:::::@::
| @::::::: @::#: :::::@:: ::::::: :::@: :: ::::::: :::@: ::@::::@:::::@::
| @::::::: @::#: :::::@:: ::::::: :::@: :: ::::::: :::@: ::@::::@:::::@::
| @::::::: @::#: :::::@:: ::::::: :::@: :: ::::::: :::@: ::@::::@:::::@::
| @::::::: @::#: :::::@:: ::::::: :::@: :: ::::::: :::@: ::@::::@:::::@::
| @::::::: @::#: :::::@:: ::::::: :::@: :: ::::::: :::@: ::@::::@:::::@::
| @::::::: @::#: :::::@:: ::::::: :::@: :: ::::::: :::@: ::@::::@:::::@::
| @::::::: @::#: :::::@:: ::::::: :::@: :: ::::::: :::@: ::@::::@:::::@::
0 +----------------------------------------------------------------------->Gi
0 11.68
このようにValgrindのMassifを使用すれば、あるプログラムのメモリ使用量のプロファイリングが簡単に行えることがわかった。