(57)【特許請求の範囲】
【請求項１】
トレーサによって取得するトレース情報の数を算出する計算機であって、
前記計算機は、プログラムの流れを制御する要素を特定する制御部を有し、前記制御部は、前記プログラムの実行前に前記要素の数を特定し、前記特定した要素の数を基に、取得するトレース情報の数を算出することを特徴とする計算機。
【請求項２】
請求項１に記載の計算機であって、
前記制御部は、前記取得するトレース情報の数に基づいて、トレース情報を格納するメモリ領域のサイズを決定することを特徴とする計算機。
【請求項３】
請求項２に記載の計算機であって、
前記制御部は、前記特定した要素の数と、前記要素の一つ分のトレース情報を格納するために必要なメモリ領域のサイズとによって、前記実行するプログラムのトレース情報を格納するメモリ領域のサイズを決定することを特徴とする計算機。
【請求項４】
請求項３に記載の計算機であって、
前記特定した要素が、処理の繰り返しを指示する要素である場合、前記制御部は、前記処理の繰り返しを指示する要素から取得するトレース情報を削除あるいは上書きしてメモリ領域に格納することを特徴とする計算機。
【請求項５】
請求項１に記載の計算機であって、
前記制御部は、前記プログラムの流れを制御する要素で構成されたツリーを生成して前記要素の数を特定することを特徴とする計算機。
【請求項６】
請求項５に記載の計算機であって、
前記制御部は、さらに前記ツリーを構成するノードを実行した記録である実行頻度をノード毎に管理し、前記実行頻度に応じて所定のプログラム実行経路を特定し、前記特定したプログラム実行経路に含まれるノードの数に基づいて取得するトレース情報の数を算出することを特徴とする計算機。
【請求項７】
請求項５に記載の計算機であって、
前記制御部は、さらに前記ツリーを構成する各ノードを実行した記録である実行頻度をノード毎に管理し、前記実行頻度から実行頻度の高いプログラム実行経路を特定し、前記特定したプログラム実行経路に含まれるノードの数に基づいて取得するトレース情報の数を算出することを特徴とする計算機。
【請求項８】
請求項６又は７に記載の計算機であって、
前記制御部は、前記取得するトレース情報の数に基づいて、トレース情報を格納するメモリ領域のサイズを決定することを特徴とする計算機。
【請求項９】
請求項８に記載の計算機であって、
前記制御部は、前記プログラムを実行し、実行して取得したトレース情報を格納するためのメモリ領域のサイズが、前記決定したメモリ領域のサイズでは不足する場合、前記決定したメモリ領域のサイズから、前記ツリーに含まれる全てのノードの数に基づいて算出されるトレース情報を格納するメモリ領域のサイズまでの大きさのメモリ領域のサイズに変更することを特徴とする計算機。
【請求項１０】
計算機がトレーサによって取得するトレース情報の数を算出する方法であって、
前記計算機は、プログラムの流れを制御する要素を前記プログラムの実行前に特定し、
前記特定した要素の数を基に、取得するトレース情報の数を算出することを特徴とする方法。
【請求項１１】
請求項１０に記載の方法であって、
前記計算機は、前記取得したトレース情報の数に基づいて、トレース情報を格納するメモリ領域のサイズを決定することを特徴とする方法。
【請求項１２】
請求項１１に記載の方法であって、
前記計算機は、前記特定した要素の数と、前記要素の一つ分のトレース情報を格納するために必要なメモリ領域のサイズとによって、前記実行するプログラムのトレース情報を格納するメモリ領域のサイズを決定することを特徴とする方法。
【請求項１３】
請求項１２に記載の方法であって、
前記特定した要素が、処理の繰り返しを指示する要素である場合、前記計算機は、前記繰り返しを指示する要素から取得するトレース情報を削除あるいは上書きしてメモリ領域に格納することを特徴とする方法。
【請求項１４】
請求項１０に記載の方法であって、
前記計算機は、前記プログラムの流れを制御する要素で構成されたツリーを生成して前記要素の数を特定することを特徴とする方法。
【請求項１５】
計算機にトレーサによって取得するトレース情報の数を算出させるプログラムであって、
前記計算機に、トレース対象プログラムの流れを制御する要素を前記トレース対象プログラムの実行前に特定させ、前記特定された要素の数を基に、取得するトレース情報の数を算出させることを特徴とするプログラム。
【請求項１６】
請求項１５に記載のプログラムであって、
前記計算機に、前記取得したトレース情報の数に基づいて、トレース情報を格納するメモリ領域のサイズを決定させることを特徴とするプログラム。
【請求項１７】
請求項１６に記載のプログラムであって、
前記計算機に、前記特定された要素の数と、前記要素の一つ分のトレース情報を格納するために必要なメモリ領域のサイズとによって、前記実行するトレース対象プログラムのトレース情報を格納するメモリ領域のサイズを決定させることを特徴とするプログラム。
【請求項１８】
請求項１７に記載のプログラムであって、
前記特定された要素が、処理の繰り返しを指示する要素である場合、前記計算機に、前記繰り返しを指示する要素から取得するトレース情報を削除あるいは上書きしてメモリ領域に格納させることを特徴とするプログラム。
【請求項１９】
請求項１５に記載のプログラムであって、
前記計算機に、前記トレース対象プログラムの流れを制御する要素で構成されたツリーを生成させて前記要素の数を特定させることを特徴とするプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、トレーサによって取得するトレース情報の数を算出する計算機、トレーサによって取得するトレース情報の数を算出する方法及びトレーサによって取得するトレース情報の数を算出させるプログラムに関する。
【背景技術】
【０００２】
企業で使用される計算機システムには、高い信頼性が求められているため、何らかの障害が発生した場合、システム保守担当者は迅速にその障害からシステムを回復させなければならない。そのため、システム保守担当者は、プログラムの構造やプログラム実行時の挙動を把握するための支援ツールであるプログラムトレーサ（以下、「トレーサ」という。）を使用し、プログラム実行における障害箇所を即時に発見している。トレーサは、実行プログラムにおけるメソッドの呼出し情報をトレースファイルとして出力するため、その出力されたトレース情報を解析することにより、障害発生を再現せずとも障害発生過程を把握することができる。
【０００３】
特許文献１に開示されているトレース情報の取得方法のように、サンプリングを用い、取得するトレース情報を間引くことによってオーバヘッドを低減する手法が存在する。しかしながら、障害解析では正確なプログラム実行経路を取得する必要があるため、サンプリングを適用するには好ましくない。また、別のオーバヘッド対策として、トレーサ内部にトレース情報を一時的に保持するバッファを用意する手法がある。この手法ではメモリ上のバッファにキャッシュすることによって、ファイルなどへの外部出力を軽減できるため、オーバヘッドを削減することができる。しかし、トレース対象となるプログラムのトレース情報がバッファのサイズを超えた場合、外部出力を行うか、もしくは取得情報の一部を上書きする必要があり、前者の場合は高オーバヘッド、後者の場合は情報損失という問題が発生する。
【０００４】
上記の問題を解決する方法として、特許文献２には、マルチタスク環境で動作する通信制御プログラムを一例とするアプリケーションプログラムを実行する際に用いられるバッファのバッファサイズを調整する技術が開示されている。特許文献２には、アプリケーションプログラムを実行する際、プログラムの実行パターンと割り当てたバッファサイズとを記録し、記録した実行パターンが再度出現したとき、それに対応するサイズのバッファを割り当てる技術が開示されている。
【先行技術文献】
【特許文献】
【０００５】
【特許文献１】特開２０１０−９２８２号公報
【特許文献２】特開平１０−６９４２９号公報
【発明の概要】
【発明が解決しようとする課題】
【０００６】
特許文献２に開示された技術は、通常の運用時のようにプログラムの実行パターンが繰り返し現れる場合、そのプログラムを一度実行した後であれば、プログラム実行１回あたりに取得されるトレース情報の数を求めることができる。しかし、システム障害が発生した場合、通常とは異なるプログラムの実行パターンが現れるため、プログラム実行１回あたりに取得されるトレース情報の数は求めることはできない。また、取得されるトレース情報の数をプログラム実行前に求めることはできないため、トレース情報を格納するために必要なバッファのサイズを予め決定しておくことは困難である。
【課題を解決するための手段】
【０００７】
本発明の代表的な一形態によれば、トレーサによって取得するトレース情報の数を算出する計算機であって、前記計算機は、プログラムの流れを制御する要素を特定する制御部を有し、前記制御部は、前記プログラムの実行前に前記要素の数を特定し、前記特定した要素の数を基に、取得するトレース情報の数を算出することを特徴とする。
【発明の効果】
【０００８】
本発明によれば、トレーサによって取得するトレース情報の数を、プログラムを実行する前に算出することができる。
【図面の簡単な説明】
【０００９】
【図１】本発明を適用した一実施の形態である第１の実施形態における計算機の全体構成を示す図である。
【図２】本発明を適用した第１の実施形態における計算機が行う処理の概要を示すフローチャートである。
【図３】本発明を適用した計算機の第１の実施形態における静的解析データ生成処理の動作を示すフローチャートである。
【図４Ａ】本発明を適用した計算機の第１の実施形態における実行プログラムを示す図である。
【図４Ｂ】本発明を適用した計算機の第１の実施形態における図４Ａに示す実行プログラムの構成要素ツリーを示す図である。
【図５】本発明を適用した計算機の第１の実施形態におけるノード生成処理の動作を示すフローチャートである。
【図６Ａ】本発明を適用した計算機の第１の実施形態におけるプログラム内に再帰メソッドを含む実行プログラムを示す図である。
【図６Ｂ】本発明を適用した計算機の第１の実施形態における図６Ａに示す実行プログラムのプログラム構成要素ツリーを示す図である。
【図７Ａ】本発明を適用した計算機の第１の実施形態におけるプログラム内に複数の再帰メソッドを含む実行プログラムを示す図である。
【図７Ｂ】本発明を適用した計算機の第１の実施形態における図７Ａに示す実行プログラムのプログラム構成要素ツリーを示す図である。
【図８Ａ】本発明を適用した計算機の第１の実施形態におけるプログラム内にループを含む実行プログラムを示す図である。
【図８Ｂ】本発明を適用した計算機の第１の実施形態における図８Ａに示す実行プログラムのプログラム構成要素ツリーを示す図である。
【図９Ａ】本発明を適用した計算機の第１の実施形態におけるプログラム内に条件分岐を含む実行プログラムを示す図である。
【図９Ｂ】本発明を適用した計算機の第１の実施形態における図９Ａに示す実行プログラムのプログラム構成要素ツリーを示す図である。
【図１０】本発明を適用した計算機の第１の実施形態におけるカレントノード変更処理の動作を示すフローチャートである。
【図１１】本発明を適用した計算機の第１の実施形態におけるカレントノード復元処理の動作を示すフローチャートである。
【図１２】本発明を適用した計算機の第１の実施形態におけるバッファサイズ計算処理の動作を示すフローチャートである。
【図１３】本発明を適用した計算機の第１の実施形態におけるプログラム書換処理の動作を示すフローチャートである。
【図１４】本発明を適用した計算機の第１の実施形態におけるプローブ挿入前のプログラムの例である。
【図１５】本発明を適用した計算機の第１の実施形態におけるプローブ挿入後のプログラムイメージを示す図である。
【図１６】本発明を適用した計算機の第１の実施形態におけるトレース情報取得処理の動作を示すフローチャートである。
【図１７Ａ】本発明を適用した計算機の第１の実施形態における実行プログラムを示す図である。
【図１７Ｂ】本発明を適用した計算機の第１の実施形態における図１７Ｂに示す実行プログラムから取得したトレース情報のバッファ格納例を示す図である。
【図１８】本発明を適用した計算機の第１の実施形態におけるトレース出力例である。
【図１９Ａ】本発明を適用した計算機の第１の実施形態における実行プログラムを示す図である。
【図１９Ｂ】本発明を適用した計算機の第１の実施形態における図１９Ａに示す実行プログラムの実行中に障害が発生した場合のトレース情報の出力例である。
【図２０】本発明を適用した一実施の形態である第２の実施形態における計算機の全体構成を示す図である。
【図２１Ａ】本発明を適用した第２の実施形態における実行プログラムを示す図である。
【図２１Ｂ】本発明を適用した第２の実施形態における図２１Ａに示す実行プログラムの実行履歴データの一例を示す図である。
【図２２】本発明を適用した第２の実施形態におけるユーザ実行データの一例を示す図である。
【図２３】本発明を適用した第２の実施形態における計算機が行う処理の概要を示すフローチャートである。
【図２４】本発明を適用した第２の実施形態における拡張バッファサイズ計算処理の動作を示すフローチャートである。
【図２５】本発明を適用した第２の実施形態における実行確率によるバッファサイズ算出処理の動作を示すフローチャートである。
【図２６Ａ】本発明を適用した第２の実施形態における実行プログラムの各ノードの実行確率表を示す表示画面の一例を示す図である。
【図２６Ｂ】本発明を適用した第２の実施形態における図２６Ａに示す実行確率表を基に選択されたプログラム構成要素ツリーを示す。
【図２７】本発明を適用した第２の実施形態におけるバッファ再割当処理の動作を示すフローチャートである。
【発明を実施するための形態】
【００１０】
［第１の実施形態］
本発明を適用した計算機システムの第１の実施形態では、プログラムの障害解析に用いるトレーサにおいて、対象システム上のプログラム1回の実行で実行され得るプログラム構成要素の数をソースプログラム及びバイナリから求めるための方法を説明する。ここで、プログラム構成要素とは、プログラムの流れを制御する要素である。具体的には、メソッド、ループ、条件分岐、再帰、引数・返り値及びローカル変数等の変数アクセスを指す。なお、本実施形態はＪａｖａ（登録商標）で記述されたシステムを対象として説明するが、他の言語で記述されたシステムに対しても有効である。また、以下の記述において、単にプログラムという場合、Ｊａｖａのバイトコード（バイナリ）を指すこととする。ただし、プログラムの具体例を用いて説明する場合においては、説明の容易化のためプログラムをソースコードの形式で表現している。
【００１１】
一般に、トレース対象のプログラム中にあるループ及び再帰内では、メソッドの呼出しをはじめとするプログラム構成要素の実行が著しく多くなってしまう。そのため、ループ及び再帰中の全てのプログラム構成要素に関する情報を取得するには、バッファサイズも取得数に比例して確保する必要があり、メモリを枯渇させる虞やメモリを計画的に使用することができない虞がある。
【００１２】
本実施形態では、トレース対象のＪａｖａプログラムからプログラム構成要素ツリーを生成する。そして、プログラム構成要素ツリーを元に、プログラム実行１回あたりのプログラム構成要素数を求め、トレース情報を格納するバッファのサイズを算出する。また、ループや再帰処理内部で障害が発生したとしても、障害を再現することなく障害発生原因を特定するために必要な、「ループや再帰が実行された履歴」、「ループや再帰の繰り返し回数」及び「繰り返しを構成する要素群の最終実行履歴」のみをバッファに格納する。これにより、プログラムにループや再帰の実行があったとしても、そのループや再帰の実行に伴う全てのトレース情報を取得する必要はないため、メモリの枯渇を生じさせることなく、メモリを計画的に使用することができる。
【００１３】
以降では、図面を用いて本実施形態の構成及び処理の流れを詳細に説明する。
図１は、本発明を適用した第１の実施形態である計算機１０１の全体構成を示す。
計算機１０１は、ＣＰＵ１０２とメモリ１０３とを有する。ＣＰＵ１０２はＪａｖａ仮想マシン１０４を実行する。Ｊａｖａ仮想マシン１０４は、プログラム読込部１０５、静的解析データ生成部１０６、静的解析データ読込部１０７、バッファサイズ計算部１０８、プログラム書換部１０９、プログラム実行部１１０、トレース情報取得部１１１及びトレース情報出力部１１２を含む。上記の機能部は、ＣＰＵ１０２と、プログラム１１３とが協働することにより実現される。
メモリ１０３は、プログラム１１３、拡張プログラム１１４、静的解析データ１１５及びトレース情報１１７を保持するバッファ１１６を有する。なお、プログラム１１３、拡張プログラム１１４、静的解析データ１１５はメモリ１０３上ではなく、外部記憶装置１１８に格納されていることもある。また、本実施形態では、メモリ１０３内にバッファ１１６を設けることとして説明するが、バッファ１１６をＣＰＵ１０２に設ける構成でもよい。
【００１４】
プログラム読込部１０５は、メモリ１０３に格納されたプログラム１１３を読込む。
静的解析データ生成部１０６は、読込んだプログラム１１３の静的解析データ１１５を生成する。なお、静的解析データ１１５は、プログラム構成要素の実行順序を示す情報である。本実施形態では、プログラム構成要素をノードとしたツリー（以下、「プログラム構成要素ツリー」という。）で、静的解析データ１１５を構成するものとする。
静的解析データ読込部１０７は、静的解析データ生成部１０６で生成された静的解析データ１１５をメモリ１０３上から読込む。
バッファサイズ計算部１０８は、読込んだ静的解析データ１１５からバッファサイズを計算し、計算したバッファサイズのバッファ１１６をメモリ１０３上に生成する。
プログラム書換部１０９は、プログラム１１３にトレース情報１１７を取得するためのプローブを挿入し、プローブを挿入した拡張プログラム１１４をメモリ１０３に配置する。
プログラム実行部１１０は、拡張プログラム１１４をメモリ１０３から読込み、実行する。
トレース情報取得部１１１は、実行した拡張プログラム１１４からトレース情報１１７を取得し、取得したトレース情報１１７をバッファ１１６に格納する。
トレース情報出力部１１２は、バッファ１１６に格納したトレース情報１１７を外部記憶装置１１８に出力する。トレース情報１１７は、プログラム１１３を実行する度に取得されるため、取得済みのトレース情報１１７を外部記憶装置１１８に出力することで、バッファ１１６の使用量やメモリ１０３の負荷を低減することができる。
【００１５】
図２は、本実施形態の計算機１０１で実行する処理全体の流れを示すフローチャートである。
はじめに、Ｓ２０１で、プログラム読込部１０５が、メモリ１０３上に格納されているプログラム１１３を読込む。
次に、Ｓ２０２で、静的解析データ生成部１０６が、静的解析データ１１５が未生成であるか否かを確認する。静的解析データ１１５が未生成である場合（Ｓ２０２：Ｙｅｓ）、Ｓ２０３で、静的解析データ生成部１０６が、メモリ１０３上にあるプログラム１１３から静的解析データ１１５を生成し、メモリ１０３に配置する（静的解析データ生成処理）。静的解析データ１１５が生成済みである場合（Ｓ２０２：Ｎｏ）、Ｓ２０４で、静的解析データ読込部１０７が、メモリ１０３上から静的解析データ１１５を読込む（静的解析データ読込処理）。
次に、Ｓ２０５で、バッファサイズ計算部１０８が、静的解析データ１１５を基にバッファサイズを計算し、メモリ１０３上に計算したバッファサイズのバッファ１１６を生成する（バッファサイズ計算処理）。
次に、Ｓ２０６で、プログラム書換部１０９が、読込んだプログラム１１３にトレース情報１１７を取得するためのプローブを挿入し、プローブ挿入済みのプログラムを拡張プログラム１１４としてメモリ１０３に配置する（プログラム書換処理）。
次に、Ｓ２０７で、プログラム実行部１１０が、拡張プログラム１１４をメモリ１０３から読込み、読込んだ拡張プログラム１１４を実行しながらトレース情報１１７を取得する（プログラム実行処理）。このとき、取得したトレース情報１１７に障害発生しているか否かを確認する。なお、障害発生とは、Ｊａｖａ仮想マシン１０４やＪａｖａ仮想マシン１０４上で動作しているスレッド（Ｊａｖａスレッド）が不正終了するような障害、任意もしくは特定の例外が発生する障害及び結果的に不正が発生する障害のことを指す。
次に、Ｓ２０８で、トレース情報取得部１１１が、取得したトレース情報１１７を、バッファ１１６に格納する（トレース情報取得処理）。
最後に、Ｓ２０９で、トレース情報出力部１１２が、システムの障害発生等を契機に、バッファ１１６に格納したトレース情報１１７を画面や外部出力デバイス（不図示）に出力する（トレース情報出力処理）。
【００１６】
以下、図２に示した各処理について、より詳細に説明する。
図３は、静的解析データ生成部１０６が行う静的解析データ生成処理（図２のＳ２０３）の処理の流れを示すフローチャートを示す。静的解析データ生成処理は、プログラム１１３を元にプログラム構成要素ツリーを生成する。なお、プログラム構成要素ツリーでは、プログラム構成要素をノードとして扱う。また、ループや条件分岐等のボディ部（ループや条件分岐内における実処理部分）に存在する構成要素は、それらを内包する構成要素（ループノード、条件分岐ノード、再帰ノード）を親ノードとする子ノードとして扱う。
【００１７】
はじめに、Ｓ３０１で、トレース対象のプログラム１１３に対して制御フロー解析を実行する。制御フロー解析とは、プログラム１１３を実行したときのプログラムの流れを、プログラム構成要素単位で抽出することをいう。
次に、Ｓ３０２で、プログラム１１３から始点メソッドを探索し、探索した始点メソッドに対応するノードを生成する。始点メソッドはＪａｖａでいうｍａｉｎメソッド、スレッドプログラミングのｒｕｎメソッド、サーブレットのｄｏＧｅｔメソッド等の処理の始点となるメソッドとする。なお、始点メソッドはユーザが任意で指定することもできる。
次に、Ｓ３０３で、生成したノードをカレントノードに設定する。カレントノードとは、プログラム構成要素ツリーに子ノードを追加する際の親ノードを意味する。
次に、Ｓ３０４で、設定したカレントノードに属するプログラム内から子ノードとなる次のプログラム構成要素を探す。
次に、Ｓ３０５で、探索したプログラム構成要素が、カレントノードに対応するプログラム構成要素の最後かどうかを確認する。すなわち、親ノードがメソッドノードなら、メソッドを構成する最終要素、ループノードならループボディを構成する最終要素であるかを確認する。
【００１８】
ここで、設定したカレントノードに対応するプログラム構成要素の最後でない場合（Ｓ３０５：Ｎｏ）、Ｓ３０６で、Ｓ３０１で抽出したプログラム構成要素を制御フロー順に読込む。
そして、Ｓ３０７で、読込んだプログラム構成要素が、ノード生成対象であるかを確認する。ここで、ノード生成対象である場合（Ｓ３０７：Ｙｅｓ）、Ｓ３０８で、ノード生成処理を行う。ノード生成対象でない場合（Ｓ３０７：Ｎｏ）、Ｓ３０５に戻る（ノード生成処理）。
次に、Ｓ３０９で、現在のカレントノードから生成した新しいノードにカレントノードの変更を行う（カレントノード変更処理）。そして、Ｓ３０５に戻りカレントノードに対応するプログラム構成要素の最後かどうかを確認する。
【００１９】
一方、設定したカレントノードがプログラム構成要素の最後である場合（Ｓ３０５：Ｙｅｓ）、Ｓ３１０で、そのカレントノードが始点メソッドのプログラム構成要素の最後であるかを確認する。
カレントノードが、始点メソッドのプログラム構成要素の最後でない場合（Ｓ３１０：Ｎｏ）、Ｓ３１１で、現在カレントノードとして設定されているカレントノードを親ノードに設定する（カレントノード復元処理）。
他方、カレントノードが、始点メソッドのプログラム構成要素の最後である場合（Ｓ３１０：Ｙｅｓ）、Ｓ３１２で、生成したプログラム構成要素ツリーを静的解析データ１１５として、メモリ１０３に出力しノード生成処理を終了する。
【００２０】
以上の静的解析データ生成処理について、具体例を用いてさらに詳細に説明する。図４Ａに、計算機で実行されるプログラム１１３の一例として、プログラム４０１を示す。また、図４Ｂに、図４Ａで示したプログラム４０１にノード生成処理を実行した場合のプログラム構成要素ツリーを示す。
まず、プログラム４０１について、制御フロー解析を行う（図３のＳ３０１）。そして、プログラム４０１からプログラムの始点メソッドであるｍａｉｎメソッド４０２を探索し、ｍａｉｎメソッド４０２のノード４０５を生成する（Ｓ３０２）。次いで、ノード４０５をカレントノードに設定し（Ｓ３０３）、ｍａｉｎメソッド４０２内の次のプログラム構成要素を探す（Ｓ３０４）。その結果、ｍａｉｎメソッド４０２内のｍｅｔｈｏｄＡ４０３のプログラム構成要素を抽出し、ｍｅｔｈｏｄＡ４０３はプログラム構成要素の最後ではなく（Ｓ３０５：Ｎｏ）、さらにノード生成対象のプログラムであるため（Ｓ３０７：Ｙｅｓ）、ｍｅｔｈｏｄＡ４０３のノード４０６を生成する（Ｓ３０８）。そして、カレントノード変更処理を行い（Ｓ３０９）、ｍｅｔｈｏｄＡ４０３内の次のプログラム構成要素としてｍｅｔｈｏｄＢ４０４を抽出し、ｍｅｔｈｏｄＢ４０４のノード４０８を生成する。
【００２１】
図５は、静的解析データ生成部１０６が行うノード生成処理（図３のＳ３０８）の処理の流れを示すフローチャートを示す。ノード生成処理は、図３のＳ３０８でノード生成対象と判断されたノード（メソッドノード、再帰ノード、ループノード及び条件分岐ノード等）を生成する。なお、プログラム構成要素の判定には、図３のＳ３０１で得た制御フロー解析の結果を用いる。
はじめに、Ｓ５０１で、ノード生成対象のプログラム構成要素がメソッドを呼出すプログラム構成要素であるか否かを確認する。メソッドを呼出すプログラム構成要素である場合（Ｓ５０１：Ｙｅｓ）、Ｓ５０２で、そのプログラム構成要素が再帰メソッドであるか否かを判断する。そして、再帰メソッドである場合（Ｓ５０２：Ｙｅｓ）、Ｓ５０３で、再帰メソッドノードを生成する。再帰メソッドでない場合（Ｓ５０２：Ｎｏ）、Ｓ５０４で、メソッドノードを生成する。
【００２２】
例えば、図６Ａは、再帰メソッド６０２を含むプログラム６０１を示す。プログラム６０１のプログラム構成要素ツリーは、図６Ｂの６０３あるいは６０８のように表現される。ｍｅｔｈｏｄＢは６０２のように自分自身のメソッドを呼び出す再帰メソッドであり、プログラム構成要素ツリー６０３のノード６０６として表現される。また、ノード６０６内に示す数字は再帰ノードに一意に割り当てられる再帰ＩＤである。また、再帰メソッドは、プログラム構成要素ツリー６０８の再帰ノード６１１のように１つのノードとして扱ってもよい。なお、図７Ａに示すプログラム７０１のように、複数メソッドにまたがる再帰呼出しの場合、プログラム構成要素ツリーは図７Ｂで表現される。
【００２３】
次に、ノード生成対象のプログラム構成要素がメソッドを呼出すプログラム構成要素でない場合（Ｓ５０１：Ｎｏ）、Ｓ５０５で、そのプログラム構成要素がループを示すプログラム構成要素であるか否かを判断する。そして、ループを示すプログラム構成要素である場合（Ｓ５０５：Ｙｅｓ）、Ｓ５０６で、ループノードを生成する。
【００２４】
例えば、図８Ａに示すループを含むプログラム８０１に対するプログラム構成要素ツリーは、図８Ｂで示される。ループを示す８０２部分は、ループノードとして図８Ｂのｆｏｒループノード８０７として示される。なお、ｆｏｒループノード８０７内の数字はループＩＤを表す。また、８０３及び８０４で示すループ内のメソッド呼出し群は、ｆｏｒループノード８０７の子ノード８０８及び８０９として示される。なお、図８は、ｆｏｒループのみの記載について例示しているが、ｗｈｉｌｅループ、ｄｏ  ｗｈｉｌｅループにおいても、ｆｏｒループと同様に、それぞれｗｈｉｌｅループノード、ｄｏ  ｗｈｉｌｅループノードと示しても良い。
【００２５】
次に、ノード生成対象のプログラム構成要素がループを示すプログラム構成要素でない場合（Ｓ５０５：Ｎｏ）、Ｓ５０７で、そのプログラム構成要素が条件分岐を示すプログラム構成要素であるか否かを判断する。条件分岐を示すプログラム構成要素である場合（Ｓ５０７：Ｙｅｓ）、Ｓ５０８で、条件分岐ノードを生成する。条件分岐を示すプログラム構成要素でない場合（Ｓ５０７：Ｎｏ）、ノード生成処理を終了する。
【００２６】
例えば、図９Ａに示す条件分岐を含むプログラム９０１のプログラム構成要素ツリーは、図９Ｂで示される。なお、９０２及び９０３の条件分岐を示す部分は、プログラム構成要素ツリー上では条件分岐ノード９０６及び９０９で表現される。なお、９０３のｅｌｓｅ  ｉｆ文は９０２のｉｆ文で生成した条件分岐ノード９０６の子ノードとして表現され、９０４のｅｌｓｅ文は９０３のｅｌｓｅ  ｉｆ文で生成した条件分岐ノード９０９の子ノードとして表現される。また、９０６及び９０９の条件分岐ノード内の数字は条件分岐ＩＤを表す。
【００２７】
図１０は、静的解析データ生成部１０６が行うカレントノード変更処理（図３のＳ３０９）の処理の流れを示すフローチャートを示す。カレントノード変更処理は、ノード生成処理（図３のＳ３０８）で生成した各ノードを、順にカレントノードに設定する。
はじめに、Ｓ１００１で、ノード生成処理（図３のＳ３０８）で生成したノードがメソッドノードであるか否かを確認する。
生成したノードが、メソッドノードである場合（Ｓ１００１：Ｙｅｓ）、Ｓ１００２で、次に読み込む構成要素の位置を呼出し先メソッドの先頭とする。
そして、Ｓ１００３で、ノード生成処理で生成したノードをカレントノードに設定し、カレントノード変更処理を終了する。
また、生成したノードが、メソッドノードでない場合（Ｓ１００１：Ｎｏ）、Ｓ１００３を実行し、カレントノード変更処理を終了する。
【００２８】
図１１は、静的解析データ生成部１０６が行うカレントノード復元処理（図３のＳ３１２）の処理の流れを示すフローチャートを示す。カレントノード復元処理は、カレントノードをカレントノードの親ノードに設定する。
はじめに、Ｓ１１０１で、プログラム構成要素の最後がメソッドであるか否かを確認する。プログラム構成要素の最後がメソッドである場合（Ｓ１１０１：Ｙｅｓ）、Ｓ１１０２で、プログラム１１３中のメソッドの呼出し元がある箇所に移動し、カレントノード復元処理を再開する。
そして、Ｓ１１０３で、現在カレントノードとして設定しているノードをカレントノードの親ノードに設定し、カレントノード復元処理を終了する。
また、プログラム構成要素の最後がメソッドでない場合(Ｓ１１０１：Ｎｏ)、Ｓ１１０３を実行しカレントノード復元処理を終了する。
以上が、静的解析データ生成処理の流れである。
【００２９】
次いで、図１２にバッファサイズ計算処理の流れを示すフローチャートを示す。バッファサイズ計算処理は、静的解析データ１１５中のプログラム構成要素ツリーのノード数に基づいてバッファサイズを算出し、求めたバッファサイズのバッファ１１６を確保する。
はじめに、Ｓ１２０１で、静的解析データ１１５からプログラム構成要素ツリーの総ノード数を取得する。例えば、図９Ｂに示すプログラム構成要素ツリーの総ノード数は９０５〜９１２の８である。
次に、Ｓ１２０２で、総ノード数をもとにバッファサイズを算出する。なお、本実施形態では、バッファサイズを、「バッファサイズ＝プログラム構成要素ツリーの総ノード数×１プログラム構成要素分のトレース情報を取得するのに必要なバッファサイズ」より求めるものとする。
次に、Ｓ１２０３で、メモリ１０３に算出したバッファサイズのバッファ領域をバッファ１１６として確保する。
【００３０】
なお、本実施形態では、メソッドの階層的な呼出し関係を把握するために、メソッドの開始時と終了時にトレース情報１１７を取得するものとするが、どのタイミングでトレース情報１１７を取得するかは、ユーザが指定することができる。また、本実施形態では、条件分岐、ループ及び再帰に関しても、メソッドの場合と同様に各要素の開始及び終了時にトレース情報１１７を取得するものとする。
【００３１】
そして、本実施形態では、１プログラム構成要素分の情報を取得するのに必要なバッファサイズを２とする。例えば、図９Ｂで示されるプログラム構成要素ツリーの総ノード数は、前述のように８であるため、図９Ａのプログラム９０１の実行により取得するトレース情報１１７を格納するために必要なバッファサイズは、８×２＝１６と算出される。また、このバッファサイズはトレーサが保持する配列の長さであり、プログラム９０１の場合、メモリ１０３上のバッファ１１６は配列長１６の配列となる。
なお、本実施形態では、１プログラム構成要素分のトレース情報１１７を取得するために必要なバッファサイズを２としているが、バッファサイズはトレース情報１１７を格納するバッファ１１６の仕様によってユーザが適宜指定することができる。
【００３２】
図１３は、プログラム書換部１０９が行うプログラム書換処理（図２のＳ２０６）の処理の流れを示すフローチャートを示す。プログラム書換処理は、プログラム読込処理（図２のＳ２０１）で読込んだプログラム１１３のトレース情報１１７を取得するために、プログラム１１３にプローブを挿入する。なお、本実施形態では、Ｊａｖａが持つＢｙｔｅｃｏｄｅ  Ｉｎｓｔｒｕｍｅｎｔａｔｉｏｎ機能を用いて、トレーサで取得する各イベントに該当するバイトコードの前後にイベントを取得するためのプローブを挿入する。
【００３３】
はじめに、Ｓ１３０１で、メモリ１０３上のプログラム１１３に読込むクラスがあるか否かを確認する。ここでいうクラスとは、Ｊａｖａソースコードから生成したバイトコード群（バイナリ）とする。読込むクラスがある場合（Ｓ１３０１：Ｙｅｓ）、Ｓ１３０２で、メモリ１０３上のプログラム１１３からクラスを読込む。
次に、Ｓ１３０３で、読込んだクラスがプログラム書換え対象のクラスか否かを確認する。読込んだクラスが書換え対象である場合（Ｓ１３０３：Ｙｅｓ）、Ｓ１３０４に進む。書換え対象のメソッドがない場合（Ｓ１３０３：Ｎｏ）、Ｓ１３０１に戻る。
次に、Ｓ１３０４で、書換え対象のメソッドがあるか否かを確認する。書換え対象のメソッドがある場合（Ｓ１３０４：Ｙｅｓ）、Ｓ１３０５で、再帰関連、メソッド関連、ループ関連及び条件分岐関連の各ノードに対応するイベント取得用プローブを挿入する。書換え対象のメソッドがない場合（Ｓ１３０４：Ｎｏ）、Ｓ１３０１に戻る。
そして、Ｓ１３０１で読込むクラスがない場合（Ｓ１３０１：Ｎｏ）、Ｓ１３０６で、書換えたプログラムを拡張プログラム１１４としてメモリ１０３に出力し、プログラム書換処理を終了する。
【００３４】
なお、本実施形態で取得するイベントは、「メソッドの開始・終了」、「再帰の開始・終了」、「ループの開始・終了」及び「条件分岐の開始・終了」であるとする。図１４に、プログラム１４０１に、「メソッドの開始・終了」、「再帰の開始・終了」、「ループの開始・終了」のプローブを挿入したイメージを示し、図１５に「条件分岐の開始・終了」のプローブを挿入したイメージを示す。
【００３５】
代表して、図１５に示すプローブ挿入後のイメージについて詳細に説明する。
ｍｅｔｈｏｄＥｎｔｒｙ １５０２は、メソッドの開始イベントを取得するためのプローブである。ｍｅｔｈｏｄＥｎｔｒｙ １５０２を用いることで、メソッド固有のＩＤを取得し、どのメソッドが開始したかを把握することができる。なお、ｍｅｔｈｏｄＥｎｔｒｙ １５０２はメソッドの処理の先頭に挿入する。
ｉｆＥｎｔｒｙ １５０３は、条件分岐の開始イベントを取得するためのプローブである。ｉｆＥｎｔｒｙ １５０３を用いることで、条件分岐固有のＩＤと条件分岐が保持する条件とを取得し、どの条件分岐が開始したかを把握することができる。なお、ｉｆＥｎｔｒｙ １５０３は条件分岐の処理の先頭に挿入する。
【００３６】
ｒｅｃｕｒｓｉｖｅＥｎｔｒｙ １５０４は、再帰の開始イベントを取得するためのプローブである。ｒｅｃｕｒｓｉｖｅＥｎｔｒｙ １５０４を用いることで、再帰固有のＩＤと再帰の繰り返し回数とを取得し、どの再帰が何回繰り返し実行されたのかを把握することができる。なお、ｒｅｃｕｒｓｉｖｅＥｎｔｒｙ １５０４は、再帰メソッドの処理の先頭に挿入する。
ｒｅｃｕｒｓｉｖｅＥｘｉｔ １５０５は、再帰の終了イベントを取得するためのプローブである。ｒｅｃｕｒｓｉｖｅＥｘｉｔ １５０５を用いることで、再帰固有のＩＤを取得し、どの再帰が実行終了したかを把握することができる。なお、ｒｅｃｕｒｓｉｖｅＥｘｉｔ １５０５は、再帰処理終了直後に挿入する。
【００３７】
ｆｏｒＬｏｏｐＥｎｔｒｙ １５０６は、ループ（ｆｏｒループ）の開始イベントを取得するためのプローブである。ｆｏｒＬｏｏｐＥｎｔｒｙ １５０６を用いることで、ループ固有のＩＤとループの繰り返し回数とを取得し、どのループが何回繰り返し実行されたかを把握することができる。なお、ｆｏｒＬｏｏｐＥｎｔｒｙ １５０６はループ内の繰り返し処理の先頭に挿入する。また、このｆｏｒＬｏｏｐＥｎｔｒｙ １５０６は何度も実行される。これは、ｆｏｒＬｏｏｐＥｎｔｒｙ １５０６の実行により、繰り返し回数を把握するためである。
ｆｏｒＬｏｏｐＥｘｉｔ １５０７は、ｆｏｒループの終了イベントを取得するためのプローブである。ｆｏｒＬｏｏｐＥｘｉｔ １５０７を用いることで、ループ固有のＩＤを取得し、どのループが実行終了したかを把握することができる。なお、ｆｏｒＬｏｏｐＥｘｉｔ １５０７は、ループ処理終了直後に挿入する。
【００３８】
ｍｅｔｈｏｄＥｘｉｔ １５０８は、メソッドの終了イベントを取得するためのプローブである。ｍｅｔｈｏｄＥｘｉｔ １５０８を用いることで、メソッド固有のＩＤを取得し、どのメソッドが終了したかを把握することができる。なお、ｍｅｔｈｏｄＥｘｉｔ １５０８は、メソッド内の処理の最後に挿入する。
ｉｆＥｘｉｔ １５０９は、条件分岐の終了イベントを取得するためのプローブである。ｉｆＥｘｉｔ １５０９を用いることで、条件分岐固有のＩＤを取得し、どの条件分岐が終了したかを把握することができる。なお、ｉｆＥｘｉｔ １５０９は条件分岐の最後に挿入する。
【００３９】
また、１５０４及び１５０６にプローブの引数として記載されているｃｏｕｎｔ１及びｃｏｕｎｔ２は、ループあるいは再帰の繰り返し回数を表している変数であり、ループあるいは再帰の開始イベントを検出する度に１ずつ増加する。なお、上記のｃｏｕｎｔ１及びｃｏｕｎｔ２の繰り返し回数は、ループＩＤ及び再帰ＩＤにつき一つ割り当てられる。
【００４０】
また、本実施形態では、１５０６及び１５０７のループに関するプローブをｆｏｒループに限定して記述しているが、ｗｈｉｌｅループあるいはｄｏ  ｗｈｉｌｅループに対してｗｈｉｌｅＬｏｏｐＥｎｔｒｙあるいはｄｏＷｈｉｌｅＬｏｏｐＥｎｔｒｙのプローブといったｆｏｒループ同様のプローブを設定しても良い。
そして、本実施形態では、各プローブの取得項目に関しても、取得項目を限定した記載となっているが、イベントの発生時間などの付加情報を取得してもよい。また、取得するイベントについても、上記した「メソッドの開始・終了」、「再帰の開始・終了」、「ループの開始・終了」及び「条件分岐の開始・終了」の８つのイベントに限定しているが、引数・返り値などの変数の取得・変更イベントなどのイベントを対象としても良い。
【００４１】
以上で説明したプログラム書換処理により、プローブを挿入したプログラム１１３を拡張プログラム１１４に書換える。また、拡張プログラム１１４は、生成後メモリ１０３に格納される。なお、このプログラム書換処理は、パッケージ名やクラス名などのユーザ指定がある場合、プログラム１１３全てに対して実施する必要はなく、指定されたメソッドに対してのみ実施してもよい。
【００４２】
図１６は、トレース情報取得部１１１が行うトレース情報取得処理（図２のＳ２０８）の処理の流れを示すフローチャートである。トレース情報取得処理では、拡張プログラム１１４を実行することで得たトレース情報１１７をメモリ１０３上のバッファ１１６に格納する。
はじめに、Ｓ１６０１で、プローブを埋め込んだ拡張プログラム１１４を実行し、トレース情報１１７を取得する。
つぎに、Ｓ１６０２で、取得したトレース情報１１７が、ループの開始あるいは再帰の開始であるか否かを確認する。トレース情報１１７がループの開始あるいは再帰の開始である場合（Ｓ１６０２：Ｙｅｓ）、Ｓ１６０３で、ループあるいは再帰による繰り返し処理を初期化するために、ループあるいは再帰開始以降のトレース情報１１７をバッファ１１６から削除する。なお、初期化オーバヘッドが大きい場合、次のトレース情報１１７の格納位置を示すポインタを、ループノードもしくは再帰ノードの位置に戻してデータを上書きするようにしてもよい。
次に、Ｓ１６０４で、ループあるいは再帰による繰り返し処理を行った回数を記録する繰り返しカウンタの値を１増加させる。
そして、Ｓ１６０５で、トレース情報１１７を繰り返しカウンタの値とともにバッファ１１６に格納し、トレース情報１１７の取得処理を終了する。繰り返しカウンタは、ループ開始及び再帰開始の各イベントに対応するトレース情報１１７とともにバッファ１１６に格納する。
また、Ｓ１６０１で取得したトレース情報１１７が、ループあるいは再帰開始でない場合（Ｓ１６０２：Ｎｏ）、Ｓ１６０６で、取得したトレース情報１１７をバッファ１１６に格納する。
【００４３】
このように、本実施形態では、バッファ１１６内に格納したループや再帰などの繰り返し部分に該当するトレース情報１１７に対しては、トレース情報１１７の削除あるいは上書きを行う。そのため、ループや再帰が実行されたという履歴と、ループや再帰の繰り返し回数、その繰り返しの最終実行履歴のみがバッファ１１６上に残ることになる。これにより、プログラム１１３中に含まれる繰り返し処理によって、ループや再帰のプログラムを実行した際に発生するトレース情報１１７を全てバッファ１１６上に残すことは不要となり、必要以上に大きいサイズのバッファ１１６を確保しておく必要や、確保しておいたバッファ１１６が不足してしまうことはなく、メモリ１０３を計画的に効率よく使用することができる。
【００４４】
次に、図１７を用いて、ループが含まれるプログラム１１３及びバッファ１１６の格納例について説明する。図１７Ａに、ループが含まれるプログラムの一例としてプログラム１７０１を示し、図１７Ｂに、バッファ１１６上での格納例を示す
図１７Ｂにおいて、「Ｃ」はメソッドの開始イベント、「Ｌｅ」はループの開始イベント、「Ｒ」はメソッドの終了イベント又「Ｌｘ」はループの終了イベントをそれぞれ示す。矢印１７２３〜１７２７は、トレース情報１１７の次の格納先を指すポインタを示す。１７０７〜１７１２は、バッファ１１６上に格納されるトレース情報の第１状態から第６状態までの状態遷移図を示す。なお、１７０７〜１７１２で示す各状態遷移図は、バッファ１１６条にトレース情報１１７を格納する様の一部を模式的に示したものである。
【００４５】
まず、図１７Ａに示すプログラム１７０１を実行すると、ｍａｉｎメソッド１７０２の開始イベント及びその内部のｍｅｔｈｏｄＡ１７０３の開始イベントが発生するため、第１状態１７０７のように、ｍａｉｎメソッドの開始イベント１７１３及びｍｅｔｈｏｄＡメソッドの開始イベント１７１４の２つの開始イベント示すトレース情報１１７が格納される。
次に、ｍｅｔｈｏｄＡ１７０３内のループ１７０４が１回実行されると、第２状態１７０８のように、ループの開始イベント１７１５、ｍｅｔｈｏｄＢ１７０５の開始イベント１７１６、ｍｅｔｈｏｄＢ１７０５の終了イベント１７１７、ｍｅｔｈｏｄＣ１７０６の開始イベント１７１８、ｍｅｔｈｏｄＣ１７０６の終了イベント１７１９を示すトレース情報１１７が格納される。
【００４６】
そして、１７１９の次の格納位置を示すポインタ１７２４をループ開始イベントＬｅ １７１５の位置に戻すことで、第３状態１７０９のようにループ開始イベントＬｅ １７１５から最後のメソッド終了イベントＲ １７１９までのトレース情報１１７を削除する。あるいは、ポインタ１７２４をループ開始イベントＬｅ １７１５の位置に戻して、次回以降はトレース情報１１７を上書きして格納していく。これは、ループ開始イベントが再度発生するため、過去に取得した繰り返しデータの削除あるいは上書きによって繰り返し部分のトレース情報１１７を同じ格納先に格納するためである。
【００４７】
次に、繰り返し部分のトレース情報１１７の初期化後、第４状態１７１０のように、再度ループの開始イベント１７１５に対応するトレース情報１１７を格納する。このとき繰り返しカウンタをトレース情報１１７の付随情報として格納する。
次に、ループ処理が終了するとき、第５状態１７１１のように、バッファ１１６の最後にループ終了イベント１７２０を示すトレース情報１１７を格納する。
最後に、第６状態１７１２のように、ｍｅｔｈｏｄＡメソッドの終了イベント１７２１及びｍａｉｎメソッドの終了イベント１７２２を示すトレース情報１１７を格納する。
【００４８】
また、バッファサイズに関しても、図１７Ａのプログラム１７０１において、ループ内にあるメソッドの数の合計が２、１メソッド分の呼出し情報を取得するのに必要なバッファサイズが２、ループの開始・終了情報が２であることから、バッファサイズは２×２＋２＝６となる。従って、１７１２のようにｍａｉｎ１７０２の開始イベント１７１３並びに１７２２及びｍｅｔｈｏｄＡ１７０３の開始イベント１７１４並びに終了イベント１７２１を除いたバッファ使用量６と一致する。なお、上記の例はループの例のみを例示しているが、再帰がある場合でも、ループの例と同様に取得するトレース情報１１７の数を算出することができる。
【００４９】
このように、従来では、ループや再帰等の繰り返しを指示する要素がプログラムに含まれている場合、取得するトレース情報の数がループや再帰の繰り返し回数に依存するため、取得するトレース情報の数を算出することはできなかった。それに伴い、そのトレース情報を格納するために必要なバッファサイズを予め把握することができなかった。しかし、本実施形態では、上記のようにループや再帰等の繰り返しを指示する要素が含まれるプログラムから取得するトレース情報の数を算出することができるため、予めトレース情報を格納するためのバッファサイズを算出することもできる。
【００５０】
図１８に、トレース情報１１７の出力例を示す。本実施形態では、図１のトレース情報出力部１１２が、トレース情報１１７をファイルとして外部記憶装置１１８に出力する。なお、図１８は、図１７Ａに示すプログラム１７０１を実行したトレース情報１１７の出力結果であり、１〜１０の各行がトレース情報１１７を示している。
トレース情報１８０１は、ｍａｉｎメソッドの開始を表している。ｍｅｔｈｏｄ＿ｅｎｔｒｙ １８０５はメソッドの開始イベント、ｍａｉｎ １８０６はｍｅｔｈｏｄ＿ｅｎｔｒｙ １８０５の対象メソッドをそれぞれ表している。
トレース情報１８０２は、ループＩＤが１のループが開始されたこと及びそのループが１００回繰り返し実行されたことを表している。ｆｏｒ＿ｌｏｏｐ＿ｅｎｔｒｙ １８０７はループの開始イベント、１８０８はループＩＤ、１８０９は繰り返しカウンタをそれぞれ表している。
トレース情報１８０３は、ｍｅｔｈｏｄＢが終了したことを表しており、ｍｅｔｈｏｄ＿ｅｘｉｔ １８１０はメソッドの終了イベント、ｍｅｔｈｏｄＢ １８１１はｍｅｔｈｏｄ＿ｅｘｉｔ １８１０の対象メソッドをそれぞれ表している。
トレース情報１８０４は、ループＩＤが１のループが終了したことを表している。ｆｏｒ＿ｌｏｏｐ＿ｅｘｉｔ １８１２はループの終了イベント、１８１３はループＩＤをそれぞれ表している。
【００５１】
最後に、本実施形態によって取得できるトレース情報の利用態様の一例について説明する。計算機１０１のプログラム実行において、ループ実行中に障害が発生した場合を想定して説明する。図１９Ａに、計算機１０１が実行するプログラム１１３の一例としてプログラム１９０１を示す。図１９Ｂに、ループ実行中に障害が発生した場合のトレース情報１１７の出力例を示す。
トレース情報１９０３より、ｆｏｒループの１０回目の繰り返しを実施していたことがわかる。また、トレース情報１９０４より、ｍｅｔｈｏｄＣが開始されたことがわかる。従って、トレース情報１９０２の出力例から、ｆｏｒループの１０回目の繰り返し中のｍｅｔｈｏｄＣで、何らかの障害が発生したことがわかる。
なお、図１９Ａはループが含まれるプログラム１９０１を実行した場合のトレース情報１１７の出力例を示しているが、再帰の場合も同様のトレース情報１１７の出力が可能である。従って、本実施形態では、ループ・再帰に対してトレース情報１１７の格納の省略を行っても、障害解析に十分なトレース情報１１７を残すことが可能である。
【００５２】
［第２の実施形態］
次に、本発明を適用した計算機の第２の実施形態について説明する。第２の実施形態は、ユーザの実行頻度が高いプログラム実行経路を構成するプログラム構成要素を選択し、それを基にバッファサイズを算出する実施形態である。
図２０に、第２の実施形態における計算機の全体構成を示す。第１の実施形態の全体構成図を示す図１と異なる構成について、以降では説明する。
【００５３】
まず、本実施形態では、Ｊａｖａ仮想マシン１０４上に、拡張バッファサイズ計算部２００１、バッファ再割当部２００２及びユーザ実行データ集計部２００３の機能部を新たに設ける。また、メモリ１０３上に、実行履歴データ２００４及びユーザ実行データ２００５を保持する。
拡張バッファサイズ計算部２００１は、プログラム構成要素ツリーから、実行確率の高いプログラム実行経路を抽出し、抽出されたプログラム実行経路に属するノード数からバッファサイズを計算する
バッファ再割当部２００２は、割当てたバッファサイズのバッファが不足する場合に、バッファの再割当をする。
ユーザ実行データ集計部２００３は、プログラムの実行履歴データ２００４をユーザ毎に集計し、ユーザ実行データ２００５を生成する。
実行履歴データ２００４は、全ユーザのプログラム構成要素ツリーの各ノード（プログラム構成要素）の実行履歴を示すデータである。
ユーザ実行データ２００５は、実行履歴データ２００４をユーザ毎にプログラム構成要素の各ノードを実行した回数を集計したデータである。
なお、実行履歴データ２００４及びユーザ実行データ２００５は、メモリ１０３上ではなく、外部記憶装置１１８に格納されることもある。
【００５４】
図２１Ｂは、図２１Ａのプログラム２１０１を実行して得られる実行履歴データ２００４の一例である。実行履歴データ２００４は、ユーザＩＤ２１０２、ノード名２１０３及びタイムスタンプ２１０４から構成される。
図２２は、図２１Ｂの実行履歴データ２００４から生成したユーザ実行データ２００５の一例である。図２２は、ユーザＩＤが「１」及び「２」であるユーザのユーザ実行データ２００５を示しており、ユーザ実行データ２００５は、ノード名２２０１と各ノードの実行回数の集計値を示す実行回数２２０２とから構成される。
【００５５】
図２３に、本発明を適用した第２の実施形態における処理の概要を示す。なお、Ｓ２３０１からＳ２３０４までの処理は、図２に示すＳ２０１からＳ２０４までの処理と同様の処理であるため説明を省略する。
まず、Ｓ２３０５で、拡張バッファサイズ計算部２００１が、メモリ１０３上の実行履歴データ２００４を読込み、読込んだ実行履歴データ２００４と静的解析データ１１５からバッファサイズを算出する。そして、算出したサイズのバッファ１１６をメモリ１０３上に確保する（拡張バッファサイズ計算処理）。
次に、Ｓ２３０６で、プログラム書換部１０９が、プログラム書換処理を実行する（プログラム書換処理）。
次に、Ｓ２３０７で、プログラム書換部１０９が、プログラム実行処理を実行する（プログラム実行処理）。なお、このとき取得したトレース情報に障害が発生しているか否かを確認する。
次に、Ｓ２３０８で、プログラム書換部１０９が、トレース取得処理を実行する（トレース情報取得処理）。なお、Ｓ２３０６〜Ｓ２３０８は、第１の実施形態と同様の処理である。
次に、Ｓ２３０９で、バッファ再割当部２００２が、割り当てたバッファ１１６が不足しているかを確認する。割り当てたバッファ１１６が不足している場合（Ｓ２３０９：Ｙｅｓ）、Ｓ２３１０で、バッファ再割当部２００２が、バッファ再割当処理を行う（バッファ再割当処理）。バッファ再割当処理は、バッファ再割当部２００２が、メモリ１０３上にあるバッファ１１６を、プログラム構成要素ツリーのノード数に基づいて計算したバッファサイズのバッファ１１６に置き換える処理である。そして、バッファ再割当処理の実行後、Ｓ２３０７に戻る。
また、割り当てたバッファ１１６が不足していない場合（Ｓ２３０９：Ｎｏ）、Ｓ２３１１でトレース情報１１７を出力し、一連の処理を終了する（トレース情報出力処理）。
【００５６】
以降では、プログラム構成要素のツリーから、実行頻度の高いプログラム実行経路を抽出する方法について説明する。本実施形態では、プログラム構成要素ツリーの各ノードにノードの実行回数を割り当て、割り当てた実行回数から実行確率を求める。そして、求めた実行確率を元に実行頻度が高いノードから構成されるプログラム実行経路を抽出する。なお、実行確率の差は、条件分岐での分岐方向の偏りに起因することが多いため、本実施形態では条件分岐における実行確率を評価する。実行確率は、「条件分岐ノードの子ノードの実行回数÷条件分岐ノードの実行回数」から求めるものとする。
【００５７】
図２４は、拡張バッファサイズ計算部２００１が行う拡張バッファサイズ計算処理の流れを示すフローチャートである。拡張バッファサイズ計算処理は、プログラム構成要素ツリーのノード数に基づくバッファサイズと、実行履歴データ２００４とから算出したユーザごとに必要とされる効率的なバッファサイズとを求め、求めたバッファサイズのバッファ１１６をメモリ１０３上に確保する。
はじめに、Ｓ２４０１で、実行履歴データ２００４をメモリ１０３から読込む。
次に、Ｓ２４０２で、静的解析データ１１５から総ノード数を取得する。
そして、Ｓ２４０３で、総ノード数に基づいて最大バッファサイズを算出する。
【００５８】
次に、Ｓ２４０４で、実行確率によるバッファサイズを算出する。バッファサイズを算出するため、ユーザ実行データ２００５に基づき、静的解析データ１１５から各条件分岐ノード及びその子ノードの実行確率を計算し、実行確率が高いプログラム実行経路を抽出する（実行確率によるバッファサイズ算出処理）。そして、そのプログラム実行経路に属するノード数から、バッファサイズを算出する。なお、Ｓ２４０４では、実行履歴データ２００４をユーザごとに集計した上で、現在実行中のユーザに該当するデータを用いて、プログラム構成要素の実行確率を求めるものとする。
次に、Ｓ２４０５で、算出したバッファサイズのバッファ領域をメモリ１０３上に確保し、処理を終了する。
このように、本実施形態では、プログラムの実行経路について実行確率を評価することで、ユーザ毎に最適なバッファサイズを決定することができる。従って、各ユーザが、実行するプログラムに応じてメモリを使用することができる。
【００５９】
図２５は、拡張バッファサイズ計算部２００１が行う実行確率によるバッファサイズ算出処理（図２４のＳ２４０４）の処理の流れを示すフローチャートである。実行確率によるバッファサイズ算出処理は、プログラム構成要素の始点メソッドのメソッドノードから順次、最近傍の条件分岐ノードをたどってプログラム実行経路を抽出し、抽出したプログラム実行経路に属するノード数からバッファサイズを算出する。
はじめに、Ｓ２５０１で、静的解析データ１１５中のプログラム構成要素ツリーの各ノードに実行回数データを付与する。なお、ここで付与される実行回数データは、ユーザ実行データ２００５の付与対象のノードに対する実行回数である。
次に、Ｓ２５０２で、プログラム構成要素ツリーの始点ノードをカレントノードに設定する。
そして、Ｓ２５０３で、未評価の条件分岐ノードがあるかを確認する。未評価の条件分岐ノードとは、実行確率を評価していない子ノードを持つ条件分岐ノードのことをいう。未評価の条件分岐ノードがある場合（Ｓ２５０３：Ｙｅｓ）、Ｓ２５０４で、カレントノードからたどれる最近傍の条件分岐ノードをカレントノードに設定する。また、未評価の条件分岐ノードがない場合（Ｓ２５０３：Ｎｏ）、Ｓ２５０６に進む。ただし、評価対象のノードはカレントノードから見てプログラム構成要素ツリーの末端方向にあるノードとする。
【００６０】
次に、Ｓ２５０５で、条件分岐ノードの子ノードの実行確率を算出する。なお、本実施形態では、子ノードの実行確率は「条件分岐ノードの子ノードの実行回数÷条件分岐ノードの実行回数」により算出するものとする。
次に、Ｓ２５０６で、条件分岐ノードの子ノード間で実行確率を比較し、実行確率が低いノードをバッファサイズの算出対象から除外する。ただし、子ノード間で実行確率を比較するとき、実行確率の差が閾値以下の場合、子ノードを除外対象としなくても良い。なお、この閾値は予め所定の値に設定するのでも、ユーザが指定するのでもよい。そして、Ｓ２５０６終了後、Ｓ２５０３に戻る。ただし、Ｓ２５０６で除外されたノードは、Ｓ２５０３の評価対象とはならないものとする。
最後に、Ｓ２５０７で、プログラム構成要素ツリー中の除外されなかったノードの数を求め、そのノード数からバッファサイズを算出して処理を終了する。なお、プログラム実行経路が複数存在する場合は、ノード数が最大となるプログラム実行経路を元にバッファサイズを算出する。また、バッファサイズの算出方法は、第１の実施形態と同様の方法で行う。
【００６１】
図２６Ａに、図２１Ａに示すプログラム２１０１の各ノードの実行確率表と、ノードを選択する際に用いる実行確率の差の閾値設定を行う表示画面の一例を示す。各ノードの実行確率表は、ノード名２６０１、ノードの実行回数２６０２及びノードの実行確率２６０３からなる。また、実行確率の差の閾値は２６０４でユーザが指定できる。ここでは、実行確率の差の閾値を１０％に設定した例を示している。これは、条件分岐ノードの実行確率の差が１０％以上である場合、その条件分岐に属する子ノードをバッファサイズの算出対象から除外することを意味する。
【００６２】
図２６Ｂは、図２６Ａに示す各ノードの実行確率を基に選択されたプログラム構成要素ツリーを示す。
はじめに、プログラム構成要素ツリーの最初の条件分岐ノードであるｉｆ＿１ ２６０６について、子ノードの実行確率を評価する。図２６Ａの各ノードの実行確率表より、子ノードであるｍｅｔｈｏｄＢ ２６０７の実行確率は３０％、ｉｆ＿２ ２６０９の条件分岐ノードの実行確率は７０％であることがわかる。従って、実行確率の差は、７０％−３０％＝４０％であるため、ｍｅｔｈｏｄＢ ２６０７以下のノードである、ｍｅｔｈｏｄＢ ２６０７及びｍｅｔｈｏｄＣ ２６０８がバッファサイズの算出対象から除外される。なお、図２６Ａでは、除外されたノードを点線で描いている。
【００６３】
図２７は、バッファ再割当部２００２が行うバッファ再割当処理（図２３のＳ２３１０）の処理の概要をフローチャートで示す。バッファ再割当処理は、拡張バッファサイズ計算部２００１が確保したバッファ１１６を、最大バッファサイズまでのバッファ１１６に割り当て直す。なお、本実施形態では、バッファ再割当処理を行うのは、プログラム１１３を実行して取得したトレース情報１１７を格納するために必要なバッファサイズが、確保したバッファサイズでは不足する場合を想定しているが、これに限られず、ユーザが指定した場合等、任意の条件で処理を実行できる。
はじめに、Ｓ２７０１で、拡張バッファサイズ計算部２００１で算出した最大バッファサイズのバッファ１１６をメモリ１０３上に確保する。
次に、Ｓ２７０２で、既存のバッファ１１６（実行履歴データ２００４に基づいて計算したバッファサイズのバッファ）内に格納してあるトレース情報１１７を確保したバッファ１１６にコピーする。
そして、Ｓ２７０３で、既存のバッファ１１６の領域を解放し、バッファ再割当処理を終了する。本処理により、プログラム中の実行確率の低い経路を実行したことで、トレース取得量がバッファサイズよりも多くなったとしても、トレース情報１１７の取得漏れを生じさせることなく、トレースを行うことができる。
【００６４】
本実施形態では、実行履歴データ２００４からシステムのユーザごとに、おおよそ必要なバッファサイズを算出することを考える。そして、バッファ１１６が不足したとき等、任意の条件で第１の実施形態に示すプログラム構成要素ツリーのノード数に基づいて計算したバッファサイズのバッファ１１６に割り当て直すことを想定している。従って、実行履歴データ２００４に基づいて計算したバッファサイズのバッファ１１６と、プログラム構成要素ツリーのノード数に基づいて計算したバッファサイズのバッファ１１６とを併用することにより、トレース情報１１７を格納するバッファ１１６をさらに効率的に利用することができる。
【符号の説明】
【００６５】
１０１計算機、１０２ＣＰＵ、１０３メモリ、１０４Ｊａｖａ仮想マシン、１０５プログラム読込部、１０６静的解析データ生成部、１０７静的解析データ読込部、
１０８バッファサイズ計算部、１０９プログラム書換部、１１０プログラム実行部、１１１トレース情報取得部、１１２トレース情報出力部、１１３プログラム、１１４拡張プログラム、１１５静的解析データ、１１６バッファ、１１７トレース情報、１１８外部記憶装置、２００１拡張バッファサイズ計算部、２００２バッファ再割当部、２００３ユーザ実行データ集計部、２００４実行履歴データ、２００５ユーザ実行データ
【図１】
0005572619.tif 000002
【図２】
0005572619.tif 000003
【図３】
0005572619.tif 000004
【図４Ａ】
0005572619.tif 000005
【図４Ｂ】
0005572619.tif 000006
【図５】
0005572619.tif 000007
【図６Ａ】
0005572619.tif 000008
【図６Ｂ】
0005572619.tif 000009
【図７Ａ】
0005572619.tif 000010
【図７Ｂ】
0005572619.tif 000011
【図８Ａ】
0005572619.tif 000012
【図８Ｂ】
0005572619.tif 000013
【図９Ａ】
0005572619.tif 000014
【図９Ｂ】
0005572619.tif 000015
【図１０】
0005572619.tif 000016
【図１１】
0005572619.tif 000017
【図１２】
0005572619.tif 000018
【図１３】
0005572619.tif 000019
【図１４】
0005572619.tif 000020
【図１５】
0005572619.tif 000021
【図１６】
0005572619.tif 000022
【図１７Ａ】
0005572619.tif 000023
【図１７Ｂ】
0005572619.tif 000024
【図１８】
0005572619.tif 000025
【図１９Ａ】
0005572619.tif 000026
【図１９Ｂ】
0005572619.tif 000027
【図２０】
0005572619.tif 000028
【図２１Ａ】
0005572619.tif 000029
【図２１Ｂ】
0005572619.tif 000030
【図２２】
0005572619.tif 000031
【図２３】
0005572619.tif 000032
【図２４】
0005572619.tif 000033
【図２５】
0005572619.tif 000034
【図２６Ａ】
0005572619.tif 000035
【図２６Ｂ】
0005572619.tif 000036
【図２７】
0005572619.tif 000037