(57)【要約】【課題】コンピュータがプログラムを実行する際に使用する資源について、コンピュータがプログラムを実行する単位であるプロセスより小さなライブラリなどの処理単位で使用量を集計すること。【解決手段】メモリ割当・開放置換部１２０がメモリ割当・開放部１３０の呼び出しをフックする。そして、メモリ割当・開放置換部１２０は、動的に使用されるメモリ量の集計に必要な情報を生成してログファイル３００に書き込むとともに、メモリ割当・開放部１３０を呼び出してメモリ割り当てや開放を行う。そして、集計処理部２００が、ログファイル３００を読み込んで動的ライブラリ毎、関数毎又はスレッド毎に、動的に使用されるメモリ量を集計する。【選択図】図２
2014149606.tif 000002
【特許請求の範囲】
【請求項１】
コンピュータに、
前記コンピュータがプログラムを実行する際に使用する資源について、前記コンピュータが前記プログラムを実行する処理単位であるプロセスより小さな処理単位で、前記資源の使用量を集計させ、
集計した前記資源の使用量を前記処理単位で出力させることを特徴とする資源使用量集計プログラム。
【請求項２】
前記資源の使用量の集計は、
前記コンピュータに、
前記資源の割り当てを要求する割り当て関数の呼び出しを、集計に必要な処理を行わせるとともに、前記割り当て関数を呼び出すフック割り当て関数の実行によりフックさせ、
前記資源の開放を要求する開放関数の呼び出しを、集計に必要な処理を行わせるとともに、前記解放関数を呼び出すフック開放関数の実行によりフックさせることを特徴とする請求項１記載の資源使用量集計プログラム。
【請求項３】
前記資源の使用量の集計は、
前記コンピュータに、
前記プログラムを実行させるとともに、前記フック割り当て関数及びフック開放関数が集計に必要な情報をそれぞれログ情報として出力させ、
前記プログラムの実行後に前記ログ情報を用いて前記資源の使用量を集計させることを特徴とする請求項２記載の資源使用量集計プログラム。
【請求項４】
前記資源の使用量の集計は、
前記コンピュータに、
前記フック割り当て関数及び前記フック開放関数が前記プログラムの実行中に、前記資源の使用量を集計させることを特徴とする請求項２記載の資源使用量集計プログラム。
【請求項５】
前記処理単位は、
動的ライブラリ、動的ライブラリに含まれる関数又はスレッドであることを特徴とする請求項１〜４のいずれか１項に記載の資源使用量集計プログラム。
【請求項６】
前記処理単位は、
動的ライブラリの各呼び出し又は動的ライブラリに含まれる関数の各呼び出しであることを特徴とする請求項１〜４のいずれか１項に記載の資源使用量集計プログラム。
【請求項７】
前記集計する処理は、
前記コンピュータに、
前記プログラムの実行時間を所定の時間間隔で分割させ、
各時間間隔における前記資源の使用量を集計させることを特徴とする請求項１〜４のいずれか１項に記載の資源使用量集計プログラム。
【請求項８】
コンピュータが、
前記コンピュータがプログラムを実行する際に使用する資源について、前記コンピュータが前記プログラムを実行する処理単位であるプロセスより小さな処理単位で、前記資源の使用量を集計し、
集計した前記資源の使用量を前記処理単位で出力することを特徴とする資源使用量集計方法。
【請求項９】
プログラムを実行する際に使用する資源について、前記プログラムを実行する処理単位であるプロセスより小さな処理単位で、前記資源の使用量を集計する集計部と、
前記集計部が集計した前記資源の使用量を前記処理単位で出力する出力部を有することを特徴とする資源使用量集計装置。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、資源使用量集計プログラム、資源使用量集計方法及び資源使用量集計装置に関する。
【背景技術】
【０００２】
近年、コンピュータプログラムは利便性や機能向上のために複雑・巨大化している。このため、プログラムをゼロから全て開発することは不可能に近く、汎用的に使用されるプログラムはライブラリ化が進んでいる。すなわち、ソフトウェア開発者は、複雑・巨大なプログラムをライブラリを使用することで効率よく開発することができる。
【０００３】
プログラム及びライブラリの開発では、メモリなどのハードウェア資源を有効に活用するために、ハードウェア資源の使用量を意識したプログラミングが必要である。そこで、ハードウェア資源の使用量に関する情報を提供する技術が開発されている。
【０００４】
例えば、多くのオペレーティングシステムは、システム全体のメモリ使用量やプロセス単位のメモリ使用量を測定・表示する事が可能である。ここで、使用メモリにはＯＳメモリ、プログラムメモリ、バッファメモリ、キャッシュメモリ、共有メモリなどがあり、一部のコマンドや集計では、使用メモリの一部を個別に表示することが可能である。
【０００５】
また、複数のサブシステムで共通に使用されるシステム共通領域のサブシステム毎の使用量を記録するメモリ使用情報テーブルを設け、メモリ使用情報テーブルの内容を出力可能とする技術が開示されている（例えば、特許文献１参照。）。また、メモリ・プールから使用することのできるメモリのサイズに基づきメモリ使用状況プロファイルを生成し、生成したメモリ使用状況プロファイルを用いて、メモリ不足例外が発生するおそれがあるか否かを予測する技術が開示されている（例えば、特許文献２参照。）。また、不測にメモリ割り当てが不可能な状態に陥ることを防ぐために、アプリケーションプログラムからメモリ領域の使用状況を確認できるようにする技術が開示されている（例えば、特許文献３参照。）。
【先行技術文献】
【特許文献】
【０００６】
【特許文献１】特開平１−３３６４２号公報
【特許文献２】特開２００７−１５７１３１号公報
【特許文献３】特開２００１−２６５６５０号公報
【発明の概要】
【発明が解決しようとする課題】
【０００７】
しかしながら、ライブラリの開発においては、ライブラリ単体ではプログラムとして動作しないため、ライブラリを呼び出すテストプログラム等を使用して試験や評価が行われており、ライブラリ単体のハードウェア資源使用量を把握することは困難である。また、ライブラリ以外の開発においても、ソフトウェア開発者がライブラリ毎のハードウェア資源使用量を把握することは困難である。例えば、ソフトウェア開発者は、システム全体や、テストプログラムに対応するプロセス単位でメモリ使用量を把握することはできるが、ライブラリ単位のメモリ使用量を把握することはできない。
【０００８】
ソースプログラムの全てが公開され、再コンパイル可能な状況であれば、ソースプログラムに改編を加えることでメモリ使用量をライブラリ毎に分類して集計することは不可能ではない。例えば、動的メモリの割り当て・開放関数の周辺にメモリ使用ライブラリ・関数名を確認するための改変をソースプログラムに加えることにより、集計は可能となる。しかしながら、多数の動的メモリ割り当て・開放関数が存在する場合には、ソースプログラムをもれなく改変するためには、多くの労力を要する。また、ライブラリ・関数名の誤りや修正漏れなどがあると正しいメモリ使用量を求めることはできない。また、商用のプログラムやライブラリが含まれる場合には、ソースプログラムは通常公開されていないため、ソフトウェア開発者はソースプログラムを改変することはできず、事実上測定・集計ができない。
【０００９】
本発明は、１つの側面では、ハードウェア資源の使用量削減に有用な情報をソフトウェア開発者に提供することを目的とする。
【課題を解決するための手段】
【００１０】
本願の開示する資源使用量集計プログラムは、１つの態様において、コンピュータに、前記コンピュータがプログラムを実行する際に使用する資源について、プロセスより小さな処理単位で、前記資源の使用量を集計させる。ここで、プロセスは、コンピュータがプログラムを実行する処理単位である。そして、前記資源使用量集計プログラムは、コンピュータに、集計した前記資源の使用量を前記処理単位で出力させる。
【発明の効果】
【００１１】
１実施態様によれば、ソフトウェア開発者は、ハードウェア資源の使用量削減に有用な情報を得ることができる。
【図面の簡単な説明】
【００１２】
【図１Ａ】図１Ａは、プログラムと動的ライブラリの標準的な呼び出し関係を説明するための図である。
【図１Ｂ】図１Ｂは、フックライブラリを用いる場合のプログラムと動的ライブラリの呼び出し関係を説明するための図である。
【図２】図２は、実施例１に係るメモリ使用量集計装置の機能構成を示す図である。
【図３】図３は、スタック情報の一例を示す図である。
【図４】図４は、ログファイルの一例を示す図である。
【図５】図５は、集計情報記憶部が動的ライブラリ毎に記憶する項目の一例を示す図である。
【図６】図６は、malloc＿hookの処理手順を示すフローチャートである。
【図７】図７は、free＿hookの処理手順を示すフローチャートである。
【図８】図８は、集計処理部による集計処理の処理手順を示すフローチャートである。
【図９】図９は、集計処理部によるライブラリ呼び出し毎の集計処理の処理手順を示すフローチャートである。
【図１０】図１０は、集計処理部による一定時間間隔毎の集計処理の処理手順を示すフローチャートである。
【図１１】図１１は、実施例２に係るメモリ使用量集計装置の機能構成を示す図である。
【図１２】図１２は、サイズテーブルの一例を示す図である。
【図１３】図１３は、メモリ使用量集計装置による集計処理と結果表示処理の概要を説明するための図である。
【図１４】図１４は、malloc＿hookの処理手順を示すフローチャートである。
【図１５】図１５は、realloc＿hookの処理手順を示すフローチャートである。
【図１６】図１６は、free＿hookの処理手順を示すフローチャートである。
【図１７】図１７は、メモリ使用量集計部による集計処理の処理手順を示すフローチャートである。
【図１８】図１８は、種々のシグナル検出によるプログラム終了時に集計結果の出力を行うことができる方法を説明するための図である。
【図１９】図１９は、本実施例に係るメモリ使用量集計プログラムを実行するコンピュータの構成を示す機能ブロック図である。
【発明を実施するための形態】
【００１３】
以下に、本願の開示する資源使用量集計プログラム、資源使用量集計方法及び資源使用量集計装置の実施例を図面に基づいて詳細に説明する。なお、実施例１では、オフラインでメモリ使用量を集計する場合について説明し、実施例２では、オンラインでメモリ使用量を集計する場合について説明する。ここで、オフラインとは、動的メモリ割り当て・開放に関するスタック情報をログファイルとして出力し、被測定プログラムの終了後、ログファイルを基に解析を実施して結果を表示する方法である。一方、オンラインとは、被測定プログラムを実行中に、逐次集計処理を実施し、被測定プログラムの終了と同時に集計結果を表示する方法である。また、これらの実施例は開示の技術を限定するものではない。
【実施例１】
【００１４】
まず、本願で使用する用語について説明する。
プログラム：コンピュータに対する命令（処理）を記述したもの。システムプログラム、アプリケーションプログラムに分類されることもあるが、本願ではアプリケーションプログラムを指す。
【００１５】
プロセス：コンピュータがプログラムを実行する場合の実行単位であって、ＯＳが管理するプログラムの実行単位。１つのプロセス内で複数の実行単位（スレッド）が割り当てられ、実行権がスケジューリングされるが、実行プログラムの単位やリソースは一つである。プログラムはソースコードや補助記憶装置（ハードディスクドライブ等）に保存された状態をも指すがプロセスはコンピュータ上で実行され稼働しているプログラムを指す。
【００１６】
動的メモリ：プログラム実行中にデータを保存するメモリ領域を動的に割り当てる方式、割り当てられたメモリを言う。プログラムは、メモリが必要になった場合に割り当て（allocate）を要求し、不要になった場合に開放（deallocate，free，release）することができる。ＯＳは要求に応じてヒープ領域から要求されたサイズの未使用のメモリ領域を割り当てる。
【００１７】
malloc系関数：動的メモリの割り当て、開放を行う際にプログラムが呼び出す関数。
void*  malloc(size_t  size)：sizeで指定されたメモリを動的に割り当て、その先頭アドレスを返す。size＿tはsize型を示し、void*はポインタ型を示す。
void*  realloc(void*  ptr,  size_t  size)：ptrで示す動的メモリを開放し、sizeで指定されたメモリを動的に割り当て、その先頭アドレスを返す。拡大・縮小前のメモリ内容は新しい領域にコピーされる。領域拡大の場合、拡大部分のメモリ内容は不定。
void  free(void*  ptr)：ptrで示す動的メモリを開放する。
void*  memalign(size_t  alignment，size_t  size)：sizeで指定されたメモリを動的に割り当て、その先頭アドレスを返す。先頭アドレスはalignmentの倍数になっている。alignmentは２のべき乗でなくてはならない。
【００１８】
次に、本願の背景技術について説明する。Linux（登録商標）／Ｃ言語では一般的に下記の４つのメモリ領域がある。本願のメモリ使用量集計は４．ヒープ領域（動的メモリ）が対象である。
１．プログラム領域：  プログラムコードが置かれる領域
２．スタティック領域：外部変数や静的変数が置かれる領域
３．スタック領域：    自動変数、関数の引数・戻り値などが置かれる領域（数十ＭＢ）
４．ヒープ領域：      動的メモリ割り当て・開放関数により使用される領域（数ＧＢ）
【００１９】
また、現代のコンピュータの多くはプログラム内蔵方式かつ一時情報をスタックに格納するスタックベースのコンピュータとなっている。スタックベースのコンピュータは、関数を呼び出すたびに実行中の関数の情報をスタック（コールスタック）に格納する。スタックは、スタックフレームから構成され、その構造はアーキテクチャに依存するが、以下の情報を格納する。
・リターンアドレス
・局所データ
・受け渡される引数
・その他
【００２０】
また、ある特定の関数においてスタック情報を解析することにより、特定の関数に至るまでの関数の呼び出し履歴やその引数の情報等を得ることができる。この履歴情報には、関数が格納されているプログラム名や動的ライブラリ名も含まれている。ここで、動的ライブラリとは、ライブラリを呼び出すプログラムにライブラリのコードが結合されることなく、プログラムの実行時に呼び出されて実行されるライブラリである。
【００２１】
また、複数の動的ライブラリに同名の関数シンボルが存在する場合、リンカは、最初に見つけたシンボルを使用する性質を有する（Linux（登録商標）の場合）。そこで、開発者は、標準関数に含まれる動的メモリ割り当て関数・開放関数を再定義し、かつ標準ライブラリよりも先にリンカに読み込ませる（LD_PRELOAD環境変数を使用する）ことで、標準ライブラリを置き換えることができる。このような手法は、関数のフックと呼ばれ、プログラム開発におけるデバッグや性能改善の為のトレース情報を得るために使用されている。
【００２２】
次に、プログラムと動的ライブラリの呼び出し関係について説明する。図１Ａは、プログラムと動的ライブラリの標準的な呼び出し関係を説明するための図であり、図１Ｂは、フックライブラリを用いる場合のプログラムと動的ライブラリの呼び出し関係を説明するための図である。ここで、フックライブラリとは、ライブラリの呼び出しをフック（横取り）するライブラリである。
【００２３】
図１Ａにおいて、ユーザプログラム１は、ｃ標準関数、malloc系関数、MPI（Messaging  Passing  Interface）関数、その他の関数を呼び出しながら処理を行う。ここで、MPI関数は、並列計算機において計算ノード間で通信を行う場合に使用される関数である。
【００２４】
図１Ａに示すように、実行コマンド「./user＿pg.out」によりユーザプログラム１が実行され、ユーザプログラム１がｃ標準関数及びmalloc系関数を呼び出すと、動的ライブラリlibc.soの対応する関数が実行される。また、プログラム１がMPI関数を呼び出すと、動的ライブラリlibmpi.soの対応する関数が実行され、プログラム１がその他の関数を呼び出すと、動的ライブラリlibm.soの対応する関数が実行される。
【００２５】
これに対して、図１Ｂに示すように、フックライブラリlibmallochook.soを用いる場合には、ユーザプログラム１がmalloc系関数を呼び出すと、動的ライブラリlibc.soの代わりにフックライブラリlibmallochook.soの対応する関数が実行される。すなわち、ユーザプログラム１がmalloc系関数を呼び出すと、動的ライブラリlibc.soはフックライブラリlibmallochook.soにフックされる。そして、フックライブラリの関数がメモリ使用量の集計処理を行うとともに動的ライブラリlibc.soの対応する関数を呼び出す。
【００２６】
このように、フックライブラリlibmallochook.soは、malloc系関数の実行を動的ライブラリlibc.soからフックすることによって、メモリ使用量の集計処理を行うことができる。なお、ユーザは、フックライブラリlibmallochook.soの使用を、実行コマンド「LD＿PRELOAD=./libmallochook.so  ./user＿pg.out」により指定することができる。この実行コマンドによりフックライブラリlibmallochook.soが標準ライブラリlibc.soより先に読み込まれ、フックライブラリlibmallochook.soによるフックが行われる。
【００２７】
次に、実施例１に係るメモリ使用量集計装置の機能構成について説明する。図２は、実施例１に係るメモリ使用量集計装置の機能構成を示す図である。図２に示すように、メモリ使用量集計装置１０は、被測定部１００と、集計処理部２００と、ログファイル３００とを有する。
【００２８】
なお、メモリ使用量集計装置１０は、コンピュータでメモリ使用量集計プログラムが実行されることにより実現される。また、被測定部１００は、コンピュータで被測定プログラムが実行されることにより実現され、集計処理部２００は、コンピュータで集計処理プログラムが実行されることにより実現される。すなわち、メモリ使用量集計プログラムは、被測定プログラムと集計処理プログラムとを有する。
【００２９】
被測定部１００は、メモリ使用量が集計される対象であり、集計に必要な情報をログファイル３００に出力する。集計処理部２００は、ログファイル３００からログ情報を読み込み、メモリ使用量を動的ライブラリ毎、関数毎又はスレッド毎に集計して出力する。なお、メモリ使用量を動的ライブラリ毎、関数毎及びスレッド毎のいずれで行うかは、被測定プログラムが実行される際にパラメータとして指定される。
【００３０】
被測定部１００は、アプリ処理部１１０と、メモリ割当・開放置換部１２０と、メモリ割当・開放部１３０とを有する。アプリ処理部１１０は、メモリ使用量が集計される対象の処理を実行する。
【００３１】
メモリ割当・開放置換部１２０は、メモリ割当・開放部１３０の呼び出しをフックする。そして、メモリ割当・開放置換部１２０は、メモリ使用量集計に必要な情報を生成してログファイル３００に出力するとともに、メモリ割当・開放部１３０を呼び出して、メモリの割り当て及び開放を行う。メモリ割当・開放置換部１２０は、初期化部１２１と、メモリ割当・開放量確認部１２２と、分別情報取得部１２３と、メモリ割当・開放呼出部１２４と、ログ情報出力部１２５とを有する。
【００３２】
初期化部１２１は、ログ情報を生成しながら行うメモリ割当・開放処理に関する初期化処理を行い、例えば、変数の初期設定などを行う。メモリ割当・開放量確認部１２２は、メモリ割当量の確認及びメモリ開放が行われる領域へのポインタの確認を行う。
【００３３】
分別情報取得部１２３は、スレッドＩＤ毎にメモリ使用量を集計する場合にはスレッドＩＤを取得し、ライブラリ毎又は関数毎にメモリ使用量を集計する場合にはスタック情報を取得する。動的ライブラリの関数が呼び出されると、動的ライブラリや関数の情報がスタックに積まれる。したがって、malloc系関数が呼び出されたときに、スタック情報を取得することにより、メモリ割当・開放置換部１２０は、malloc系関数を呼び出した関数の順番に関する情報を取得することができる。
【００３４】
図３は、スタック情報の一例を示す図である。図３では、８個の要素がスタックされている。要素「７」及び要素「６」は、プログラムが実行されると常にスタックされる情報であり、要素「５」がメイン関数の呼び出しを示している。そして、要素「５」から要素「０」に向かって関数func＿0、func＿a0、func＿a1、func＿b0、malloc＿hookが順次呼ばれている。メインから最初に呼ばれている動的ライブラリの関数は要素「３」のliba.soのfunc＿a0であり、最終的にmalloc関数を呼んでいるのはlibb.soのfunc＿b0である。なお、図３は、Linux（登録商標）において、backtrace＿symbols関数によりスタックの情報がバックトレース翻訳された場合の例を示したものである。
【００３５】
また、動的ライブラリ毎又は関数毎にメモリ使用量を集計する場合、集計処理部２００は、メインから最初に呼ばれている動的ライブラリ毎又は関数毎に集計を行うことも、最終的にmalloc系関数を呼んでいる動的ライブラリ毎又は関数毎に集計を行うこともできる。また、集計処理部２００は、メインから最初に呼ばれている動的ライブラリ又は関数から、最終的にmalloc系関数を呼んでいる動的ライブラリ又は関数までの全てについて動的ライブラリ毎又は関数毎に集計を行うこともできる。いずれの方法で動的ライブラリ毎又は関数毎に集計を行うかは、被測定プログラムが実行される際にパラメータとして指定される。
【００３６】
メモリ割当・開放呼出部１２４は、メモリ割当・開放部１３０を呼び出し、メモリの割り当て及びメモリの開放を行う。ログ情報出力部１２５は、呼び出されたmalloc系関数毎に関数名、割り当てられた又は開放されたメモリ量、割り当てられた又は開放されたメモリ領域へのポインタをスレッドＩＤ又はスタック情報とともにログファイル３００に出力する。
【００３７】
図４は、ログファイル３００の一例を示す図である。図４に示すように、ログファイル３００は、呼び出されたmalloc系関数毎に関数名i、ptri、sizei、スタック情報iを記憶する（１≦ｉ≦ｎ）。ここで、ptriは割り当てられた又は開放されたメモリ領域へのポインタであり、sizeiは割り当てられた又は開放されたメモリ量である。なお、図４は、動的ライブラリ毎又は関数毎にメモリ使用量を集計する場合を示すが、スレッド毎にメモリ量を集計する場合には、スタック情報iの代わりにスレッドＩＤが記憶される。
【００３８】
図２に戻って、メモリ割当・開放部１３０は、ヒープ領域からのメモリの割り当て及びヒープ領域へのメモリの開放を行う。なお、メモリ割当・開放置換部１２０は、図１Ｂに示したlibmallochook.soに対応し、メモリ割当・開放部１３０は、図１Ｂに示したlibc.soに対応する。
【００３９】
集計処理部２００は、初期化部２１０と、ログ情報読出部２２０と、メモリ使用量集計部２３０と、集計情報記憶部２４０と、メモリ使用量表示部２５０とを有する。初期化部２１０は、集計処理に関する初期化処理を行い、例えば、変数の初期設定などを行う。ログ情報読出部２２０は、ログファイル３００からログ情報を読み出す。
【００４０】
メモリ使用量集計部２３０は、ログ情報読出部２２０により読み出されたログ情報を用いて、動的ライブラリ毎、関数毎又はスレッド毎にメモリ使用量を集計する。
【００４１】
集計情報記憶部２４０は、メモリ使用量集計部２３０により集計されるメモリ使用量を記憶する。図５は、集計情報記憶部２４０が動的ライブラリ毎に記憶する項目の一例を示す図である。図５に示すように、集計情報記憶部２４０は、動的ライブラリ毎に、ライブラリ名、サイズ、最小値、最大値、malloc呼出回数、realloc呼出回数、free呼出回数、memalign呼出回数を記憶する。
【００４２】
ここで、ライブラリ名は、メモリ使用量が集計される動的ライブラリの名前であり、サイズは集計されたメモリ使用量である。割り当てられたメモリ量はサイズに加算され、開放されたメモリ量はサイズから減算される。
【００４３】
最大値は、割り当てと開放が行われる中で、ある時点で割り当てられているメモリ量の最大値であり、最小値は、割り当てと開放が行われる中で、ある時点で割り当てられているメモリ量の最小値である。例えば、全体の処理の中で初期化処理を行う関数では、主にメモリの割り当てが行われるため、他の関数と比較して最大値が正の大きな値となる。一方、全体の処理の中で終了処理を行う関数では、主にメモリの開放が行われるため、他の関数と比較して最小値が負の大きな値となる。
【００４４】
malloc呼出回数はmalloc関数が呼び出された回数であり、realloc呼出回数はrealloc関数が呼び出された回数であり、free呼出回数はfree関数が呼び出された回数であり、memalign呼出回数は、memalign関数が呼び出された回数である。
【００４５】
なお、集計情報記憶部２４０は、関数毎にメモリ使用量を集計する場合には、ライブラリ名の代わりに関数名を記憶し、スレッド毎にメモリ使用量を集計する場合には、ライブラリ名の代わりにスレッドＩＤを記憶する。
【００４６】
メモリ使用量表示部２５０は、集計情報記憶部２４０が記憶する集計情報を表示装置に出力する。また、メモリ使用量表示部２５０は、集計情報をプリンタや記憶装置など他の装置に出力することもできる。
【００４７】
次に、メモリ割当・開放置換部１２０の処理手順について、malloc＿hook及びfree＿hookを例として説明する。ここで、malloc＿hookとは、図１Ｂに示した動的ライブラリlibmallochook.soのmallocであり、free_hookとは、図１Ｂに示した動的ライブラリlibmallochook.soのfreeである。
【００４８】
図６は、malloc＿hookの処理手順を示すフローチャートである。図６に示すように、malloc＿hookは、malloc処理を行う（ステップＳ１）。すなわち、malloc＿hookは、malloc＿org(size)を呼び出し、呼び出し結果をptrにセットする。ここで、malloc＿orgは、図１Ｂに示したlibc.soのmallocであり、sizeは割り当てを要求するメモリ量である。
【００４９】
そして、malloc＿hookは、ptrがNULLでないかを判定し（ステップＳ２）、NULLである場合には、処理を終了し、NULLでない場合には、メモリが割り当てられたので、ログ出力処理を行う（ステップＳ３）。具体的には、malloc＿hookは、ログ出力処理として、関数名、ptr、size及びスタック情報をログファイル３００に出力する。ここで、関数名は“malloc”であり、スタック情報はbacktrace＿symbolsにより翻訳された結果である。そして、malloc＿hookは、処理を終了する。
【００５０】
このように、malloc＿hookが、mallocの呼び出しをフックして、メモリ使用量の集計に必要な情報をログファイル３００に出力することで、集計処理部２００は、メモリ使用量を集計することができる。なお、realloc＿hook及びmemalign＿hookは、ステップＳ１において、malloc＿org(size)の代わりにrealloc＿org(prev＿ptr，size)及びmemalign＿org(size)をそれぞれ呼び出す点を除いて、malloc＿hookと同様な処理を行う。
【００５１】
図７は、free＿hookの処理手順を示すフローチャートである。図７に示すように、free＿hookは、ptrで指定されている開放領域について、ログ出力処理を行う（ステップＳ１１）。具体的には、free＿hookは、ログ出力処理として、関数名、ptr及びスタック情報をログファイル３００に出力する。ここで、関数名は“free”であり、スタック情報はbacktrace＿symbolsにより翻訳された結果である。また、ptrは、free＿hookが呼ばれる際に開放領域を指定する引数として与えられる。
【００５２】
そして、free＿hookは、free処理を行う（ステップＳ１２）。すなわち、free＿hookは、free＿org(ptr)を呼び出す。ここで、free＿orgは、図１Ｂに示したlibc.soのfreeである。そして、free＿hookは、処理を終了する。
【００５３】
このように、free＿hookが、freeの呼び出しをフックして、メモリ使用量の集計に必要な情報をログファイル３００に出力することで、集計処理部２００は、メモリ使用量を集計することができる。
【００５４】
次に、集計処理部２００による集計処理の処理手順について説明する。図８は、集計処理部２００による集計処理の処理手順を示すフローチャートである。図８に示すように、集計処理部２００は、ログファイル３００からログを読み込み、malloc系関数を特定する（ステップＳ２１）。
【００５５】
そして、集計処理部２００は、trace[ln]に”.so“を含むか否かを判定する（ステップＳ２２）。ここで、”loop  ln=(ntrace-3)…0“と”loop  ln“は、２つの”loop  ln“で挟まれた処理を、lnを(ntrace-3)から0まで順に変化させて繰り返すループ処理を示す。また、trace[ln]は、図３に示したスタック情報の各要素を示し、ntraceはスタック情報の要素数−１を示す。図３に示した例では、ntrace=7であり、trace[ntrace-3]は要素「４」を示す。すなわち、ステップＳ２２では、集計処理部２００は、関数が呼び出された順にスタック情報をサーチしてライブラリ名を見つけるとループから抜ける。
【００５６】
そして、集計処理部２００は、見つけたライブラリの名前をlib＿nameにセットする（ステップＳ２３）。すなわち、ステップＳ２２及びステップＳ２３により、集計処理部２００は、メイン関数から最初に呼び出された動的ライブラリを特定する。
【００５７】
そして、集計処理部２００は、特定した動的ライブラリの名前がlib＿statに登録されているか否かを判定する（ステップＳ２４）。ここで、lib＿statは集計情報記憶部２４０に対応する構造体であり、lib＿stat[idx].libnameは、集計情報記憶部２４０が記憶するidx番目のライブラリ名を示す。すなわち、集計処理部２００は、idxを0からnum＿lib−１まで順に変化させて、特定した動的ライブラリの名前が集計情報記憶部２４０に登録されているかを判定する。ここで、num＿libは集計情報記憶部２４０が記憶する動的ライブラリの数である。
【００５８】
そして、集計処理部２００は、特定した動的ライブラリの名前がlib＿statに登録されている場合には、ステップＳ２６に進み、特定した動的ライブラリの名前がlib＿statに登録されていない場合には、ライブラリ追加を行う（ステップＳ２５）。
【００５９】
具体的には、集計処理部２００は、ライブラリ追加処理として、lib＿stat[num＿lib].libname=lib＿nameによりライブラリ名を登録し、lib＿stat[num＿lib].mem＿size=0により集計値を「０」に初期化し、num＿lib++によりnum＿libに「１」を加える。また、集計処理部２００は、lib＿stat[num＿lib].max＿size=0、lib＿stat[num＿lib].min＿size=0により最大値、最小値を「０」に初期化する。なお、mem＿size、max＿size、min＿sizeは、それぞれ図５のサイズ、最大値、最小値に対応する。
【００６０】
そして、集計処理部２００は、動的ライブラリが使用するメモリ量を集計する（ステップＳ２６）。具体的には、集計処理部２００は、lib＿stat[idx].malloc＿cnt++により、malloc呼出回数malloc＿cntに「１」を加え、lib＿stat[idx].mem＿size+=sizeにより、割り当てられたメモリ量をサイズmem＿sizeに加える。また、集計処理部２００は、lib＿stat[idx].max＿size、lib＿stat[idx].min＿sizeを必要に応じて更新する。すなわち、ステップＳ２４〜ステップＳ２６により、集計処理部２００は、使用メモリ量を動的ライブラリで分類して集計する分類集計処理を行う。
【００６１】
なお、ここでは、特定されたmalloc系関数がmallocである場合を示したが、特定された関数がrealloc、free及びmemalignの場合には、realloc回数、free呼出回数及びmemalign呼出回数がそれぞれ「１」加えられる。また、特定された関数がfreeである場合には、sizeは開放量に「−１」を掛けた値である。
【００６２】
そして、集計処理部２００は、全てのログについて処理を終了したか否かを判定し（ステップＳ２７）、全てのログについて処理を終了した場合には、集計処理を終了し、処理を行っていないログがある場合には、ステップＳ２１に戻って、次のmalloc系関数を特定する。
【００６３】
このように、集計処理部２００が、被測定プログラムの実行とは別に、ログファイル３００を用いてメモリ使用量の集計を行うことによって、メモリ使用量集計装置１０は、オフラインでメモリ使用量の集計を行うことができる。
【００６４】
なお、ここでは、集計処理部２００は、動的ライブラリ毎にメモリ使用量を集計したが、ライブラリ名の代わりに呼び出された関数名を特定し、ライブラリ名の代わりに関数名を集計情報記憶部２４０に登録することによって、関数毎にメモリ使用量を集計できる。また、集計処理部２００は、ライブラリ名の代わりにスレッドＩＤを集計情報記憶部２４０に登録することによって、スレッド毎にメモリ使用量を集計できる。
【００６５】
また、ここでは、集計処理部２００は、ステップＳ２２でライブラリを特定する場合に、lnを(ntrace-3)から0まで順に変化させたが、lnを0から(ntrace-3)に順に変化させることによって、malloc系関数を最後に呼び出した動的ライブラリを特定することもできる。すなわち、集計処理部２００は、malloc系関数を最後に呼び出したライブラリ毎にメモリ使用量を集計することもできる。さらに、集計処理部２００は、１つのmalloc系関数の呼び出し毎に複数の動的ライブラリを特定し、メイン関数の呼び出しからmalloc系関数の呼び出しまでの複数の動的ライブラリについて、メモリ使用量を集計することもできる。
【００６６】
また、ここでは、集計処理部２００は、同じ動的ライブラリが複数回呼び出された場合に、複数回の呼び出しで使用した全メモリ量を集計する。しかしながら、動的ライブラリが複数回呼び出された場合に、集計処理部２００は、呼び出し毎に使用するメモリ量を集計することもできる。そこで、集計処理部２００によるライブラリ呼び出し毎の集計処理の処理手順について説明する。
【００６７】
図９は、集計処理部２００によるライブラリ呼び出し毎の集計処理の処理手順を示すフローチャートである。図９に示すように、集計処理部２００は、ログファイル３００からログを読み込み、malloc系関数を特定する（ステップＳ３１）。
【００６８】
そして、集計処理部２００は、lnを(ntrace-3)から0まで順に変化させて、trace[ln]に”.so“を含むか否かを判定する（ステップＳ３２）。すなわち、集計処理部２００は、関数が呼び出された順にスタック情報をサーチしてライブラリ名を見つけるとループから抜ける。
【００６９】
そして、集計処理部２００は、見つけたライブラリの名前をlib＿nameにセットする（ステップＳ３３）。すなわち、ステップＳ３２及びステップＳ３３により、集計処理部２００は、メイン関数から最初に呼び出された動的ライブラリを特定する。
【００７０】
そして、集計処理部２００は、特定した動的ライブラリの名前が前回のmalloc系関数呼び出しで特定された動的ライブラリの名前last＿libnameであるか否かを判定する（ステップＳ３４）。
【００７１】
そして、集計処理部２００は、特定した動的ライブラリの名前が前回のmalloc系関数呼び出しで特定された動的ライブラリの名前である場合には、動的ライブラリの名前は登録済みであるので、ステップＳ３６に進む。一方、特定した動的ライブラリの名前が前回のmalloc系関数呼び出しで特定された動的ライブラリの名前でない場合には、ライブラリ追加を行う（ステップＳ３５）。具体的には、集計処理部２００は、ライブラリ追加処理として、lib＿stat[num＿lib].libname=lib＿nameによりライブラリ名を登録し、lib＿stat[num＿lib].mem＿size=0により集計値を「０」に初期化し、num＿lib++によりnum＿libに「１」を加える。また、集計処理部２００は、lib＿stat[num＿lib].max＿size=0、lib＿stat[num＿lib].min＿size=0により最大値、最小値を「０」に初期化する。
【００７２】
そして、集計処理部２００は、動的ライブラリが使用するメモリ量を集計する（ステップＳ３６）。具体的には、集計処理部２００は、lib＿stat[idx].malloc＿cnt++により、malloc呼出回数malloc＿cntに「１」を加え、lib＿stat[idx].mem＿size+=sizeにより、割り当てられたメモリ量をサイズmem＿sizeに加える。また、集計処理部２００は、lib＿stat[idx].max＿size、lib＿stat[idx].min＿sizeを必要に応じて更新する。すなわち、ステップＳ３４〜ステップＳ３６により、集計処理部２００は、各動的ライブラリの呼び出しで分類して使用メモリ量を集計する分類集計処理を行う。
【００７３】
なお、ここでは、特定されたmalloc系関数がmallocである場合を示したが、特定された関数がrealloc、free及びmemalignの場合には、realloc回数、free呼出回数及びmemalign呼出回数がそれぞれ「１」加えられる。また、特定された関数がfreeである場合には、sizeは開放量に「−１」を掛けた値である。
【００７４】
そして、集計処理部２００は、全てのログについて処理を終了したか否かを判定し（ステップＳ３７）、全てのログについて処理を終了した場合には、集計処理を終了し、処理を行っていないログがある場合には、ステップＳ３１に戻って、次のmalloc系関数を特定する。
【００７５】
このように、同じ動的ライブラリが複数回呼び出された場合に、集計処理部２００は、呼び出し毎に使用するメモリ量を集計することによって、１回の動的ライブラリの呼び出しで使用するメモリ量を求めることができる。
【００７６】
なお、集計処理部２００は、メモリ使用量の集計を一定時間間隔毎に行うこともできるそこで、集計処理部２００による一定時間間隔毎の集計処理の処理手順について説明する。
【００７７】
図１０は、集計処理部２００による一定時間間隔毎の集計処理の処理手順を示すフローチャートである。図１０に示すように、集計処理部２００は、str＿num＿libを「０」に初期化する（ステップＳ４１）。ここで、str＿num＿libは、集計情報記憶部２４０のインデックスidxに関して一定時間間隔毎に設定される検索開始番号を示す。すなわち、集計情報記憶部２４０は、一定の時間間隔毎に使用される複数のブロックに分割され、検索開始番号の先頭を示す。
【００７８】
そして、集計処理部２００は、ログファイル３００からログを読み込み、malloc系関数を特定する（ステップＳ４２）。そして、集計処理部２００は、trace[ln]に”.so“を含むか否かを判定する（ステップＳ４３）。
【００７９】
そして、集計処理部２００は、見つけたライブラリの名前をlib＿nameにセットする（ステップＳ４４）。すなわち、ステップＳ４２及びステップＳ４４により、集計処理部２００は、メイン関数から最初に呼び出された動的ライブラリを特定する。
【００８０】
そして、集計処理部２００は、経過時間がインターバル以上であるか否か、すなわち、一定時間が経過したか否かを判定し（ステップＳ４５）、経過時間がインターバル以上である場合には、一定時間が経過したので、str＿num＿libにnum＿libを設定する（ステップＳ４６）。すなわち、集計処理部２００は、集計情報記憶部２４０の次のブロックの使用を開始する。
【００８１】
そして、集計処理部２００は、特定した動的ライブラリの名前がlib＿statに登録されているか否かを判定する（ステップＳ４７）。すなわち、集計処理部２００は、idxをstr＿num＿libからnum＿lib−１まで順に変化させて、特定した動的ライブラリの名前が集計情報記憶部２４０の現在のブロックに登録されているかを判定する。ここで、num＿libは全ブロックを通じて集計情報記憶部２４０が記憶するライブラリの数である。
【００８２】
そして、集計処理部２００は、特定した動的ライブラリの名前がlib＿statの現在のブロックに登録されている場合には、ステップＳ４９に進む。一方、特定した動的ライブラリの名前がlib＿statの現在のブロックに登録されていない場合には、集計処理部２００は、ライブラリ追加を行う（ステップＳ４８）。具体的には、集計処理部２００は、ライブラリ追加処理として、lib＿stat[num＿lib].libname=lib＿nameによりライブラリ名を登録し、lib＿stat[num＿lib].mem＿size=0により集計値を「０」に初期化し、num＿lib++によりnum＿libに「１」を加える。また、集計処理部２００は、lib＿stat[num＿lib].max＿size=0、lib＿stat[num＿lib].min＿size=0により最大値、最小値を「０」に初期化する。
【００８３】
そして、集計処理部２００は、動的ライブラリが使用するメモリ量を集計する（ステップＳ４９）。具体的には、集計処理部２００は、lib＿stat[idx].malloc＿cnt++により、malloc呼出回数malloc＿cntに「１」を加え、lib＿stat[idx].mem＿size+=sizeにより、割り当てられたメモリ量をサイズmem＿sizeに加える。また、集計処理部２００は、lib＿stat[idx].max＿size、lib＿stat[idx].min＿sizeを必要に応じて更新する。すなわち、ステップＳ４５〜ステップＳ４９により、集計処理部２００は、使用メモリ量をブロック毎に動的ライブラリで分類して集計する分類集計処理を行う。
【００８４】
なお、ここでは、特定されたmalloc系関数がmallocである場合を示したが、特定された関数がrealloc、free及びmemalignの場合には、realloc回数、free呼出回数及びmemalign呼出回数がそれぞれ１加えられる。また、特定された関数がfreeである場合には、sizeは開放量に「−１」を掛けた値である。
【００８５】
そして、集計処理部２００は、全てのログについて処理を終了したか否かを判定し（ステップＳ５０）、全てのログについて処理を終了した場合には、集計処理を終了し、処理を行っていないログがある場合には、ステップＳ４２に戻って、次のmalloc系関数を特定する。
【００８６】
このように、集計処理部２００が、メモリ使用量の集計を一定時間間隔毎に行うことによって、メモリ使用量集計装置１０は、メモリ使用量の時間的推移に関する情報を収集することができる。
【００８７】
上述してきたように、実施例１では、メモリ割当・開放置換部１２０がメモリ割当・開放部１３０の呼び出しをフックする。そして、メモリ割当・開放置換部１２０は、動的に使用されるメモリ量の集計に必要な情報を生成してログファイル３００に書き込むとともに、メモリ割当・開放部１３０を呼び出してメモリ割り当てや開放を行う。そして、集計処理部２００が、ログファイル３００を読み込んで動的ライブラリ毎、関数毎又はスレッド毎に、動的に使用されるメモリ量をオフラインで集計する。
【００８８】
したがって、動的ライブラリ開発において、開発者は、動的ライブラリを変更することなく、動的に使用されるメモリ量を動的ライブラリ毎、関数毎又はスレッド毎に把握することができ、メモリ使用量の削減に有用な情報を得ることができる。また、開発者が想定していない異常終了が発生しても、そこに至るまでのログが保存済みであるため、その時点までのメモリ使用量の集計が可能である。また、一度の測定結果を基に異なる集計が可能である。
【００８９】
また、実施例１では、集計処理部２００は、動的ライブラリの各呼び出し毎又は動的ライブラリに含まれる関数の各呼び出し毎に、動的に使用されるメモリ量を集計することもできる。したがって、動的ライブラリ開発において、開発者は、動的に使用されるメモリ量を動的ライブラリの各呼び出し毎又は関数の各呼び出し毎に把握することができ、省メモリ化に有用な情報を得ることができる。
【００９０】
また、実施例１では、集計処理部２００は、動的ライブラリ毎、関数毎又はスレッド毎に、動的に使用されるメモリ量を一定の時間間隔毎に集計することもできる。したがって、動的ライブラリ開発において、開発者は、動的に使用されるメモリ量の時間推移を把握することができ、省メモリ化に有用な情報を得ることができる。
【実施例２】
【００９１】
ところで、上記実施例１では、被測定プログラムがログ情報を出力し、集計処理部２００がログ情報を用いてオフラインでメモリ使用量を集計する場合について説明した。しかしながら、被測定プログラムを実行しながらオンラインでメモリ使用量を集計することもできる。そこで、実施例２では、被測定プログラムを実行しながらオンラインでメモリ使用量を集計するメモリ使用量集計装置について説明する。
【００９２】
まず、実施例２に係るメモリ使用量集計装置の機能構成について説明する。図１１は、実施例２に係るメモリ使用量集計装置の機能構成を示す図である。図１１に示すように、メモリ使用量集計装置２０は、被測定・集計部４００を有する。被測定・集計部４００は、コンピュータで被測定プログラムが実行されることにより実現され、メモリ使用量が集計される対象であるとともに、集計処理も行う。すなわち、被測定・集計部４００は、集計に必要な情報をログファイル３００に出力する代わりに集計処理を行う。
【００９３】
被測定・集計部４００は、アプリ処理部１１０と、メモリ割当・開放置換部４２０と、集計情報記憶部４２７と、サイズテーブル４２９と、メモリ割当・開放部１３０とを有する。なお、ここでは説明の便宜上、図２に示した各部と同様の役割を果たす機能部については同一符号を付すこととしてその詳細な説明を省略する。
【００９４】
メモリ割当・開放置換部４２０は、メモリ割当・開放部１３０の呼び出しをフックする。そして、メモリ割当・開放置換部４２０は、メモリ使用量集計を行うとともに、メモリ割当・開放部１３０を呼び出して、メモリの割り当て及び開放を行う。メモリ割当・開放置換部４２０は、初期化部４２１と、メモリ割当・開放量確認部１２２と、分別情報取得部１２３と、メモリ使用量集計部４２６と、メモリ割当・開放呼出部１２４と、メモリ使用量表示部４２８とを有する。
【００９５】
初期化部４２１は、メモリ使用量を集計しながら行うメモリ割当・開放処理に関する初期化処理を行い、例えば、変数の初期設定などを行う。メモリ使用量集計部４２６は、スタック情報や集計情報記憶部４２７を用いて動的メモリの使用量を集計する。メモリ使用量表示部４２８は、集計情報記憶部４２７が記憶する集計情報を表示装置に出力する。また、メモリ使用量表示部４２８は、集計情報をプリンタや記憶装置など他の装置に出力することもできる。
【００９６】
集計情報記憶部４２７は、メモリ使用量集計部４２６により集計されるメモリ使用量を記憶する。なお、集計情報記憶部４２７は、図２に示した集計情報記憶部２４０と同様のデータ構造を有する。サイズテーブル４２９は、動的に割り当てられたメモリ領域のポインタiからサイズiを検索するために用いられる。図１２は、サイズテーブル４２９の一例を示す図である。図１２に示すように、サイズテーブル４２９は、ポインタiとサイズi（１≦ｉ≦ｎ）とを対応付けて記憶する。
【００９７】
次に、メモリ使用量集計装置２０による集計処理と結果表示処理の概要について説明する。図１３は、メモリ使用量集計装置２０による集計処理と結果表示処理の概要を説明するための図である。
【００９８】
図１３に示すように、メモリ使用量集計装置２０は、被測定プログラムを実行し、malloc系関数や非malloc系関数を呼び出しながら各種処理を行う（ステップＳ６１）。そして、被測定プログラムからmalloc系関数の呼び出しが行われると、malloc系関数の呼び出しがフックされ、補助プログラムとしてのフック関数による処理が行われる。
【００９９】
フック関数は、初期化フラグを用いて初期化済みか否かを判定し（ステップＳ６２）、初期済みでない場合には、初期化処理を行う（ステップＳ６３）。具体的には、フック関数は、atexit関数を用いて、被測定プログラムが正常終了（プログラマが想定した範囲の異常終了を含む）した後に動作させる関数として結果表示関数を登録する。また、フック関数は初期化済みであるか否かを示す初期化フラグを初期化済みに変更する。そして、フック関数は、malloc系関数処理及び集計処理を行う（ステップＳ６４）。
【０１００】
被測定プログラムの処理が終了すると、atexeit関数を用いて登録された結果表示関数が起動される。そして、結果表示関数が集計結果表示を行う（ステップＳ６５）。
【０１０１】
このように、被測定プログラムが正常終了した後に結果表示関数を動作させることによって、メモリ使用量集計装置２０は、集計結果を表示することができる。なお、被測定プログラムの正常終了と同時に集計結果を表示させるためには、スタックを操作し、メイン関数の終了に伴う戻りアドレスを操作し、集計結果を表示する関数のアドレスに変更すれば良い。そして、集計結果表示関数の終了に伴う戻りアドレスを本来の戻りアドレスに変更すれば良い。
【０１０２】
次に、メモリ割当・開放置換部４２０の処理手順について、malloc＿hook、realloc＿hook及びfree＿hookを例として説明する。図１４は、malloc＿hookの処理手順を示すフローチャートである。
【０１０３】
図１４に示すように、malloc＿hookは、malloc処理を行う（ステップＳ８１）。すなわち、malloc＿hookは、malloc＿org(size)を呼び出し、呼び出し結果をptrにセットする。
【０１０４】
そして、malloc＿hookは、ptrがNULLでないかを判定し（ステップＳ８２）、NULLである場合には、処理を終了し、NULLでない場合には、メモリが割り当てられたので、集計処理を行う（ステップＳ８３）。具体的には、malloc＿hookは、集計処理として、メモリ使用量の加算、メモリ使用量の最大・最小の更新及びmalloc呼出回数のインクリメントを行う。
【０１０５】
そして、malloc＿hookは、ポインタ（ptr）及びサイズ（size）のサイズテーブル４２９への登録を行う（ステップＳ８４）。そして、malloc＿hookは、処理を終了する。
【０１０６】
このように、malloc＿hookが、mallocの呼び出しをフックして、メモリ使用量の集計処理を行うことで、メモリ使用量集計装置２０は、オンラインでメモリ使用量を集計することができる。なお、memalign＿hookは、ステップＳ８１において、malloc＿org(size)の代わりにmemalign＿org(size)をそれぞれ呼び出す点を除いて、malloc＿hookと同様な処理を行う。
【０１０７】
図１５は、realloc＿hookの処理手順を示すフローチャートである。図１５に示すように、realloc＿hookは、prev＿ptrがNULLでないかを判定し（ステップＳ９１）、NULLである場合には、prev＿sizeに「０」を設定し（ステップＳ９２）、ステップＳ９７に進む。ここで、prev＿ptrは、realloc呼び出しにおいて開放領域へのポインタを示す引数であり、prev＿sizeは、realloc呼び出しにおいて開放領域のサイズを示す引数である。
【０１０８】
一方、prev＿ptrがNULLでない場合には、開放領域が指定されているので、realloc＿hookは、開放領域のメモリサイズを検索する（ステップＳ９３）。すなわち、realloc＿hookは、prev＿ptrを検索キーとしてサイズテーブル４２９を検索する。
【０１０９】
そして、realloc＿hookは、サイズテーブル４２９にprev_ptrが有るか否かを判定し（ステップＳ９４）、ない場合には、引数の指定が正しくないので、関数不適切使用メッセージを表示し（ステップＳ９５）、処理を終了する。一方、サイズテーブル４２９にprev_ptrが有る場合には、realloc＿hookは、prev_ptrに対応するサイズを取得し、prev＿sizeとする（ステップＳ９６）。
【０１１０】
そして、realloc＿hookは、realloc処理を行う（ステップＳ９７）。すなわち、realloc＿hookは、realloc＿org(prev＿ptr，size)を呼び出し、呼び出し結果をptrにセットする。
【０１１１】
そして、realloc＿hookは、ptrがNULLでないかを判定し（ステップＳ９８）、NULLである場合には、処理を終了し、NULLでない場合には、メモリの再割り当てが行われたので、集計処理を行う（ステップＳ９９）。具体的には、realloc＿hookは、集計処理として、メモリ使用量の加減算、メモリ使用量の最大・最小の更新及びrealloc呼出回数のインクリメントを行う。
【０１１２】
そして、realloc＿hookは、サイズテーブル４２９の更新を行い（ステップＳ１００）、処理を終了する。
【０１１３】
このように、realloc＿hookが、reallocの呼び出しをフックして、メモリ使用量の集計処理を行うことで、メモリ使用量集計装置２０は、オンラインでメモリ使用量を集計することができる。
【０１１４】
図１６は、free＿hookの処理手順を示すフローチャートである。図１６に示すように、free＿hookは、まず、引数ptrが非NULLであるか確認する（ステップＳ１１１）。NULLの場合には、free＿hookは、ステップＳ１１２にて、sizeに「０」を与え、集計処理（ステップＳ１１７）に飛ぶ。ptrが非NULLの場合、free＿hookは、開放領域のメモリサイズを検索する（ステップＳ１１３）。すなわち、free＿hookは、ptrを検索キーとしてサイズテーブル４２９を検索する。
【０１１５】
そして、free＿hookは、サイズテーブル４２９にptrが有るか否かを判定し（ステップＳ１１４）、ない場合には、引数の指定が正しくないので、関数不適節メッセージを表示（ステップＳ１１５）し、処理を終了する。一方、サイズテーブル４２９にptrが有る場合には、free＿hookは、ptrに対応するサイズを取得後、サイズテーブル４２９より開放領域の削除を行う（ステップＳ１１６）。
【０１１６】
その後、free＿hookは、集計処理を行う（ステップＳ１１７）。具体的には、free＿hookは、集計処理として、メモリ使用量の減算、メモリ使用量の最大・最小の更新及びfree呼出回数のインクリメントを行う。そして、free＿hookは、free処理を行い（ステップＳ１１８）、処理を終了する。
【０１１７】
このように、free＿hookが、freeの呼び出しをフックして、メモリ使用量の集計処理を行うことで、メモリ使用量集計装置２０は、オンラインでメモリ使用量を集計することができる。
【０１１８】
次に、メモリ使用量集計部４２６による集計処理の処理手順について説明する。図１７は、メモリ使用量集計部４２６による集計処理の処理手順を示すフローチャートである。なお、図１７に示す集計処理は、図１４のステップＳ８４、図１５のステップ１００、及び、図１６のステップＳ１１４の処理に対応する。
【０１１９】
図１７に示すように、メモリ使用量集計部４２６は、スタック情報をバックトレース翻訳し、有効要素数をntraceに設定する（ステップＳ１２１）。そして、メモリ使用量集計部４２６は、trace[ln]に”.so“を含むか否かを判定する（ステップＳ１２２）。
【０１２０】
そして、メモリ使用量集計部４２６は、見つけたライブラリの名前をlib＿nameにセットする（ステップＳ１２３）。すなわち、ステップＳ１２２及びステップＳ１２３により、メモリ使用量集計部４２６は、メイン関数から最初に呼び出された動的ライブラリを特定する。
【０１２１】
そして、メモリ使用量集計部４２６は、特定した動的ライブラリの名前がlib＿statに登録されているか否かを判定する（ステップＳ１２４）。ここで、lib＿statは集計情報記憶部４２７に対応する構造体であり、lib＿stat[idx].libnameは、集計情報記憶部４２７が記憶するidx番目のライブラリ名を示す。すなわち、メモリ使用量集計部４２６は、idxを0からnum＿lib−１まで順に変化させて、特定した動的ライブラリの名前が集計情報記憶部４２７に登録されているかを判定する。ここで、num＿libは集計情報記憶部４２７が記憶するライブラリの数である。
【０１２２】
そして、メモリ使用量集計部４２６は、特定した動的ライブラリの名前がlib＿statに登録されている場合には、ステップＳ１２６に進み、特定した動的ライブラリの名前がlib＿statに登録されていない場合には、ライブラリ追加を行う（ステップＳ１２５）。具体的には、メモリ使用量集計部４２６は、ライブラリ追加処理として、lib＿stat[num＿lib].libname=lib＿nameによりライブラリ名を登録し、lib＿stat[num＿lib].mem＿size=0により集計値を「０」に初期化し、num＿lib++によりnum＿libに「１」を加える。また、メモリ使用量集計部４２６は、lib＿stat[num＿lib].max＿size=0、lib＿stat[num＿lib].min＿size=0により最大値、最小値を「０」に初期化する。
【０１２３】
そして、メモリ使用量集計部４２６は、動的ライブラリが使用するメモリ量を集計する（ステップＳ１２６）。具体的には、メモリ使用量集計部４２６は、lib＿stat[idx].malloc＿cnt++により、malloc呼出回数malloc＿cntに「１」を加え、lib＿stat[idx].mem＿size+=sizeにより、割り当てられたメモリ量をサイズmem＿sizeに加える。また、メモリ使用量集計部４２６は、lib＿stat[idx].max＿size、lib＿stat[idx].min＿sizeを必要に応じて更新する。
【０１２４】
なお、ここでは、malloc系関数がmallocである場合を示したが、関数がrealloc、free及びmemalignの場合には、realloc回数、free呼出回数及びmemalign呼出回数がそれぞれ１加えられる。また、特定された関数がfreeである場合には、sizeは開放量に「−１」を掛けた値である。
【０１２５】
このように、メモリ使用量集計部４２６が、オンラインでメモリ使用量の集計を行うことによって、メモリ使用量集計装置２０は、ログファイルを用いることなくメモリ使用量の集計を行うことができる。
【０１２６】
なお、ここでは、メモリ使用量集計部４２６は、動的ライブラリ毎にメモリ使用量を集計したが、ライブラリ名の代わりに呼び出された関数名を特定し、ライブラリ名の代わりに関数名を集計情報記憶部４２７に登録することによって、関数毎にメモリ使用量を集計できる。また、メモリ使用量集計部４２６は、ライブラリ名の代わりにスレッドＩＤを集計情報記憶部４２７に登録することによって、スレッドにメモリ使用量を集計できる。
【０１２７】
また、ここでは、メモリ使用量集計部４２６は、ステップＳ１２２でライブラリを特定する場合に、lnを(ntrace-3)から0まで順に変化させたが、lnを0から(ntrace-3)に順に変化させることによって、malloc系関数を最後に呼び出した動的ライブラリを特定することもできる。すなわち、メモリ使用量集計部４２６は、malloc系関数を最後に呼び出したライブラリ毎にメモリ使用量を集計することもできる。さらに、メモリ使用量集計部４２６は、１つのmalloc系関数の呼び出し毎に複数の動的ライブラリを特定し、メイン関数の呼び出しからmalloc系関数の呼び出しまでの複数の動的ライブラリについて、メモリ使用量を集計することもできる。
【０１２８】
上述してきたように、実施例２では、メモリ使用量集計装置２０は、被測定プログラムの実行中にメモリ使用量の分類集計処理をオンラインで実施し、被測定プログラムの終了と同時に集計結果を表示する。したがって、メモリ使用量集計装置２０は、ログファイルを使用する必要がなく、ディスク記憶領域を節約することができる。
【０１２９】
なお、実施例２では、メモリ使用量集計装置２０は、atexit関数を用いて結果表示関数を登録することにより、被測定プログラムの終了時に集計結果の出力を行った。しかしながら、メモリ使用量集計装置２０は、種々のシグナル検出によるプログラム終了（プログラマが想定していない異常終了）時には集計結果の出力を行うことができない。そこで、種々のシグナル検出によるプログラム終了時に集計結果の出力を行うことができる方法について説明する。
【０１３０】
図１８は、種々のシグナル検出によるプログラム終了時に集計結果の出力を行うことができる方法を説明するための図である。図１８に示すように、被測定プログラムとは別の集計プログラムが、親プロセスとしてプロセスフォークを行い（ステップＳ１３１）、被測定プログラムを子プロセスとして動作させる。そして、被測定プログラムは、各種処理を行いながら共有メモリ領域に集計結果を書き込む（ステップＳ１３２）。そして、共有メモリ領域が集計結果を保持する。
【０１３１】
そして、親プロセスは、子プロセスの終了を確認し（ステップＳ１３３）、子プロセスの終了時に共有メモリ領域の集計結果を読み込み、集計結果の表示処理を行う（ステップＳ１３４）。なお、親プロセスは、共有メモリ領域の代わりに、プロセス間通信を用いて集計情報を得ることもできる。
【０１３２】
また、近年では計算処理をより高速で処理を行う目的や、単一ノードのメモリ量を超えるデータを同時に処理することを目的に、分散メモリ型の並列計算機が利用されている。分散メモリ型の並列計算機は、複数の計算機（計算ノード）を高速なネットワークで接続したものである。計算ノード間で処理されたデータはネットワークを通して必要に応じて通信・共有化され、結果として分散メモリ型の並列計算機は単一の計算機に比較して高速に処理を行ったり、個別のノードで異なるデータを保存することで巨大なデータ処理を行ったりする。
【０１３３】
このような仕組みを提供するシステムソフトとしてMPIが最も広く利用されている。MPIでは、”mpiexec”コマンドにより各計算ノードにおいてプロセスが立ち上がり、その子プロセスとして任意のプログラムによる並列処理が実現されている。
【０１３４】
MPIプログラムでは各ノードで動作するプロセスが協調して動作することが不可欠であり、一つの計算ノードのプロセスが終了すると親プロセスである”mpiexec”が全ての計算ノードで実行されている子プロセス（ユーザプログラム）を強制終了させる。これはユーザプログラムからすると想定外の異常終了であり、集計結果を表示することなくMPIプログラムは終了されてしまう。また、図１８で説明した方法をとっても、ここで言うユーザプログラムが図１８の親プロセスに相当し、親プロセスが異常終了されてしまうため、集計結果は表示されない。このようなケースでは、ソフトウェア開発者は、”mpiexec”コマンドを改良し、図１８と同様な仕組みを組み込むことで、集計結果が表示されない問題を解決することができる。
【０１３５】
なお、実施例１及び２では、メモリ使用量集計装置について説明したが、メモリ使用量集計装置が有する構成をソフトウェアによって実現することで、同様の機能を有するメモリ使用量集計プログラムを得ることができる。そこで、メモリ使用量集計プログラムを実行するコンピュータについて説明する。
【０１３６】
図１９は、実施例に係るメモリ使用量集計プログラムを実行するコンピュータの構成を示す機能ブロック図である。図１９に示すように、コンピュータ６００は、メインメモリ６１０、ＣＰＵ（Central  Processing  Unit）６２０、ＬＡＮ（Local  Area  Network）インタフェース６３０、ＨＤＤ（Hard  Disk  Drive）６４０、スーパーＩＯ（Input  Output）６５０を有する。また、コンピュータ６００は、ＤＶＩ（Digital  Visual  Interface）６６０、ＯＤＤ（Optical  Disk  Drive）６７０を有する。
【０１３７】
メインメモリ６１０は、プログラムやプログラムの実行途中結果などを記憶するメモリである。ＣＰＵ６２０は、メインメモリ６１０からプログラムを読み出して実行する中央処理装置である。ＣＰＵ６２０は、メモリコントローラを有するチップセットを含む。
【０１３８】
ＬＡＮインタフェース６３０は、コンピュータ６００をＬＡＮ経由で他のコンピュータに接続するためのインタフェースである。ＨＤＤ６４０は、プログラムやデータを格納するディスク装置であり、スーパーＩＯ６５０は、マウスやキーボードなどの入力装置を接続するためのインタフェースである。ＤＶＩ６６０は、液晶表示装置を接続するインタフェースであり、ＯＤＤ６７０は、ＤＶＤの読み書きを行う装置である。
【０１３９】
ＬＡＮインタフェース６３０は、ＰＣＩエクスプレスによりＣＰＵ６２０に接続され、ＨＤＤ６４０及びＯＤＤ６７０は、ＳＡＴＡ（Serial  Advanced  Technology  Attachment）によりＣＰＵ６２０に接続される。スーパーＩＯ６５０は、ＬＰＣ（Low  Pin  Count）によりＣＰＵ６２０に接続される。
【０１４０】
そして、コンピュータ６００において実行されるメモリ使用量集計プログラムは、ＤＶＤに記憶され、ＯＤＤ６７０によってＤＶＤから読み出されてコンピュータ６００にインストールされる。あるいは、メモリ使用量集計プログラムは、ＬＡＮインタフェース６３０を介して接続された他のコンピュータシステムのデータベースなどに記憶され、これらのデータベースから読み出されてコンピュータ６００にインストールされる。そして、インストールされたメモリ使用量集計プログラムは、ＨＤＤ６４０に記憶され、メインメモリ６１０に読み出されてＣＰＵ６２０によって実行される。
【０１４１】
なお、実施例１及び２では、ヒープ領域の使用量を集計する場合について説明したが、本発明はこれに限定されるものではなく、スタック領域など他のメモリ領域、不揮発性記憶装置など他のハードウェア資源の使用量を集計する場合にも同様に適用することができる。
【０１４２】
以上の実施例１〜２を含む実施形態に関し、さらに以下の付記を開示する。
【０１４３】
（付記１）コンピュータに、
前記コンピュータがプログラムを実行する際に使用する資源について、前記コンピュータが前記プログラムを実行する処理単位であるプロセスより小さな処理単位で、前記資源の使用量を集計させ、
集計した前記資源の使用量を前記処理単位で出力させることを特徴とする資源使用量集計プログラム。
【０１４４】
（付記２）前記資源の使用量の集計は、
前記コンピュータに、
前記資源の割り当てを要求する割り当て関数の呼び出しを、集計に必要な処理を行わせるとともに、前記割り当て関数を呼び出すフック割り当て関数の実行によりフックさせ、
前記資源の開放を要求する開放関数の呼び出しを、集計に必要な処理を行わせるとともに、前記解放関数を呼び出すフック開放関数の実行によりフックさせることを特徴とする付記１記載の資源使用量集計プログラム。
【０１４５】
（付記３）前記資源の使用量の集計は、
前記コンピュータに、
前記プログラムを実行させるとともに、前記フック割り当て関数及びフック開放関数が集計に必要な情報をそれぞれログ情報として出力させ、
前記プログラムの実行後に前記ログ情報を用いて前記資源の使用量を集計させることを特徴とする付記２記載の資源使用量集計プログラム。
【０１４６】
（付記４）前記資源の使用量の集計は、
前記コンピュータに、
前記フック割り当て関数及び前記フック開放関数が前記プログラムの実行中に、前記資源の使用量を集計させることを特徴とする付記２記載の資源使用量集計プログラム。
【０１４７】
（付記５）前記処理単位は、
動的ライブラリ、動的ライブラリに含まれる関数又はスレッドであることを特徴とする付記１〜４のいずれか１項に記載の資源使用量集計プログラム。
【０１４８】
（付記６）前記処理単位は、
動的ライブラリの各呼び出し又は動的ライブラリに含まれる関数の各呼び出しであることを特徴とする付記１〜４のいずれか１項に記載の資源使用量集計プログラム。
【０１４９】
（付記７）前記集計する処理は、
前記コンピュータに、
前記プログラムの実行時間を所定の時間間隔で分割させ、
各時間間隔における前記資源の使用量を集計させることを特徴とする付記１〜４のいずれか１項に記載の資源使用量集計プログラム。
【０１５０】
（付記８）コンピュータが、
前記コンピュータがプログラムを実行する際に使用する資源について、前記コンピュータが前記プログラムを実行する処理単位であるプロセスより小さな処理単位で、前記資源の使用量を集計し、
集計した前記資源の使用量を前記処理単位で出力することを特徴とする資源使用量集計方法。
【０１５１】
（付記９）プログラムを実行する際に使用する資源について、前記プログラムを実行する処理単位であるプロセスより小さな処理単位で、前記資源の使用量を集計する集計部と、
前記集計部が集計した前記資源の使用量を前記処理単位で出力する出力部を有することを特徴とする資源使用量集計装置。
【０１５２】
（付記１０）メモリと該メモリに接続されたＣＰＵとを有する資源使用量集計装置において、
前記ＣＰＵに、
前記コンピュータがプログラムを実行する際に使用する資源について、前記コンピュータが前記プログラムを実行する処理単位であるプロセスより小さな処理単位で、前記資源の使用量を集計させ、
集計した前記資源の使用量を前記処理単位で出力させることを特徴とする資源使用量集計装置。
【０１５３】
（付記１１）コンピュータに、
前記コンピュータがプログラムを実行する際に使用する資源について、前記コンピュータが前記プログラムを実行する処理単位であるプロセスより小さな処理単位で、前記資源の使用量を集計させ、
集計した前記資源の使用量を前記処理単位で出力させることを特徴とする資源使用量集計プログラムを記憶したコンピュータ読み取り可能な記憶媒体。
【符号の説明】
【０１５４】
１    ユーザプログラム
１０，２０    メモリ使用量集計装置
１００    被測定部
１１０    アプリ処理部
１２０，４２０    メモリ割当・開放置換部
１２１，４２１    初期化部
１２２    メモリ割当・開放量確認部
１２３    分別情報取得部
１２４    メモリ割当・開放呼出部
１２５    ログ情報出力部
１３０    メモリ割当・開放部
２００    集計処理部
２１０    初期化部
２２０    ログ情報読出部
２３０    メモリ使用量集計部
２４０，４２７    集計情報記憶部
２５０，４２８    メモリ使用量表示部
３００    ログファイル
４００    被測定・集計部
４２６    メモリ使用量集計部
４２９    サイズテーブル
６００    コンピュータ
６１０    メインメモリ
６２０    ＣＰＵ
６３０    ＬＡＮインタフェース
６４０    ＨＤＤ
６５０    スーパーＩＯ
６６０    ＤＶＩ
６７０    ＯＤＤ
【図１Ａ】
2014149606.tif 000003
【図１Ｂ】
2014149606.tif 000004
【図２】
2014149606.tif 000005
【図３】
2014149606.tif 000006
【図４】
2014149606.tif 000007
【図５】
2014149606.tif 000008
【図６】
2014149606.tif 000009
【図７】
2014149606.tif 000010
【図８】
2014149606.tif 000011
【図９】
2014149606.tif 000012
【図１０】
2014149606.tif 000013
【図１１】
2014149606.tif 000014
【図１２】
2014149606.tif 000015
【図１３】
2014149606.tif 000016
【図１４】
2014149606.tif 000017
【図１５】
2014149606.tif 000018
【図１６】
2014149606.tif 000019
【図１７】
2014149606.tif 000020
【図１８】
2014149606.tif 000021
【図１９】
2014149606.tif 000022