(57)【要約】【課題】実行履歴採取時のプログラムの負荷を抑えること。【解決手段】予測コード挿入部１２がオブジェクトの生存期間を予測するためのコードを挿入し、生存期間予測部１５が、予測コード挿入部１２により挿入されたコードに基づいて、オブジェクトの生存期間を予測する。そして、オブジェクトの生存期間に基づいて、採取コード挿入部１１が、実行履歴を記録するためのコードを切り替えて挿入し、実行履歴出力部１６が、採取コード挿入部１１により挿入されたコードに基づいて、実行履歴を出力する。【選択図】図６
2018097817.tif 000002
【特許請求の範囲】
【請求項１】
オブジェクトの生存期間を予測する予測部と、
前記オブジェクトを使用するプログラムの実行中にエラーが発生した場合に前記オブジェクトのアドレスを実行履歴として採取するために前記アドレスを一時記憶する方式を前記予測部による予測結果に基づいて切り替える切替部と
を有することを特徴とする情報処理装置。
【請求項２】
前記切替部は、前記アドレスを採取するコードを前記プログラムのコードに挿入する際に切り替えることによって前記方式を切り替えることを特徴とする請求項１に記載の情報処理装置。
【請求項３】
前記切替部は、前記プログラムの実行中に前記アドレスを採取するコードを切り替えることによって前記方式を切り替えることを特徴とする請求項１に記載の情報処理装置。
【請求項４】
前記予測部は、前記オブジェクトを参照するメソッドの実行時間よりも前記オブジェクトの生存期間が長いか否かを予測し、
前記切替部は、前記オブジェクトを参照するメソッドの実行時間よりも前記オブジェクトの生存期間が長い場合には、前記オブジェクトのアドレスを一時記憶し、前記オブジェクトを参照するメソッドの実行時間よりも前記オブジェクトの生存期間が長くない場合には、前記オブジェクトのアドレスを整数に変換して一時記憶することを特徴とする請求項１、２又は３に記載の情報処理装置。
【請求項５】
前記予測部は、所定の閾値よりも前記オブジェクトの生存期間が長いか否かを予測し、
前記切替部は、前記所定の閾値よりも前記オブジェクトの生存期間が長い場合には、前記オブジェクトのアドレスを一時記憶し、前記所定の閾値よりも前記オブジェクトの生存期間が長くない場合には、前記オブジェクトのアドレスを整数に変換して一時記憶することを特徴とする請求項１、２又は３に記載の情報処理装置。
【請求項６】
前記予測部は、前記オブジェクトが使用されたときに使用時刻を記録したタグを前記オブジェクトに付加し、前記オブジェクトがガベージコレクターにより回収されたときに回収時刻を記録し、前記使用時刻と前記回収時刻に基づいて前記生存期間を予測することを特徴とする請求項１〜５のいずれか１つに記載の情報処理装置。
【請求項７】
コンピュータが、
オブジェクトの生存期間を予測し、
前記オブジェクトを使用するプログラムの実行中にエラーが発生した場合に前記オブジェクトのアドレスを実行履歴として採取するために前記アドレスを一時記憶する方式を、予測した結果に基づいて切り替える
処理を実行することを特徴とする情報処理方法。
【請求項８】
コンピュータに、
オブジェクトの生存期間を予測し、
前記オブジェクトを使用するプログラムの実行中にエラーが発生した場合に前記オブジェクトのアドレスを実行履歴として採取するために前記アドレスを一時記憶する方式を、予測した結果に基づいて切り替える
処理を実行させることを特徴とするプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、情報処理装置、情報処理方法及びプログラムに関する。
【背景技術】
【０００２】
プログラムの実行中に発生したエラーの原因を調査するために、プログラムの実行履歴を採取することが行われる。プログラムの開発者は、実行履歴に基づいてソースコードを解析することによって、プログラムの不具合箇所を特定する。
【０００３】
なお、コンパイル時に、新たに作成されるオブジェクトへの永続リファレンスが生成されるか否かの確認結果に応じて、オブジェクトを第１のメモリ領域か又は少なくとも一部を効率的に書き込みが行える第２のメモリ領域に作成する技術がある。この技術によれば、効率的に書き込みが行える第２のメモリを効率よく利用することができる。
【０００４】
また、生成されるオブジェクトの生存期間がルートクラスについてのオブジェクトの生存期間に含まれず、生成されるオブジェクトが属する集合に対応する寿命平均値が閾値以上の時に、該オブジェクトを長寿命オブジェクトとして外部ヒープに配置する技術がある。この技術によれば、長寿命のオブジェクトをガベージコレクションの対象外とすることで、オブジェクトを利用するプログラムを高速化することができる。
【先行技術文献】
【特許文献】
【０００５】
【特許文献１】特表２００６−５２５５６８号公報
【特許文献２】特開２０１０−４４５３２号公報
【発明の概要】
【発明が解決しようとする課題】
【０００６】
プログラムの実行履歴を採取しようとすると、採取用のコードをプログラムに挿入して実行することで、プログラムの負荷が高くなるという問題がある。したがって、プログラムの実行履歴を採取する場合には、プログラムの負荷をできるだけ抑える必要がある。
【０００７】
本発明は、１つの側面では、実行履歴採取時のプログラムの負荷を抑えることを目的とする。
【課題を解決するための手段】
【０００８】
１つの態様では、情報処理装置は、予測部と切替部とを有する。予測部は、オブジェクトの生存期間を予測する。切替部は、オブジェクトを使用するプログラムの実行中にエラーが発生した場合にオブジェクトのアドレスを実行履歴として採取するためにアドレスを一時記憶する方式を予測部による予測結果に基づいて切り替える。
【発明の効果】
【０００９】
１つの側面では、本発明は、実行履歴採取時のプログラムの負荷を抑えることができる。
【図面の簡単な説明】
【００１０】
【図１Ａ】図１Ａは、実行履歴の採取を説明するための第１の図である。
【図１Ｂ】図１Ｂは、実行履歴の採取を説明するための第２の図である。
【図１Ｃ】図１Ｃは、実行履歴の採取を説明するための第３の図である。
【図１Ｄ】図１Ｄは、実行履歴の採取を説明するための第４の図である。
【図１Ｅ】図１Ｅは、実行履歴の採取を説明するための第５の図である。
【図１Ｆ】図１Ｆは、実行履歴の採取を説明するための第６の図である。
【図１Ｇ】図１Ｇは、実行履歴の採取を説明するための第７の図である。
【図２】図２は、オブジェクトの生存期間を説明するための図である。
【図３】図３は、実施例１に係る情報処理装置による処理の概要のフローを示すフローチャートである。
【図４】図４は、実施例１に係る情報処理装置による処理例を説明するための図である。
【図５】図５は、実施例１に係る情報処理装置の構成を示す図である。
【図６】図６は、システムプログラムの機能構成を示す図である。
【図７】図７は、オブジェクトの使用時刻及び回収時刻を記録する処理の一例を説明するための図である。
【図８】図８は、予測結果記憶部の一例を示す図である。
【図９】図９は、実行履歴記憶部の一例を示す図である。
【図１０】図１０は、バイトコード記憶部の一例を示す図である。
【図１１】図１１は、情報処理装置による処理のフローを示すフローチャートである。
【図１２】図１２は、ステップＳ１１の処理のフローを示すフローチャートである。
【図１３】図１３は、ステップＳ１２の処理のフローを示すフローチャートである。
【図１４】図１４は、ステップＳ１３の処理のフローを示すフローチャートである。
【図１５】図１５は、ステップＳ１４の処理のフローを示すフローチャートである。
【図１６】図１６は、実行状態の文字列表現を説明するための図である。
【図１７】図１７は、変換前のバイトコードを示す図である。
【図１８】図１８は、予測用バイトコードを示す図である。
【図１９】図１９は、採取用のバイトコードを示す図である。
【図２０】図２０は、採取された実行履歴を示す図である。
【図２１】図２１は、実施例２に係る情報処理装置による処理のフローを示すフローチャートである。
【図２２】図２２は、オブジェクト生存期間の予測結果が全て長命であるとして実行履歴の採取用コードが挿入された採取用バイトコードを示す図である。
【図２３】図２３は、オブジェクト生存期間の予測結果に基づいて実行履歴の採取用コードが再挿入された採取用バイトコードを示す図である。
【図２４】図２４は、予測結果を実行履歴採取時に参照する方法を説明するための図である。
【図２５】図２５は、実施例３に係る情報処理装置による処理のフローを示すフローチャートである。
【図２６】図２６は、実施例４に係る情報処理装置による処理のフローを示すフローチャートである。
【発明を実施するための形態】
【００１１】
以下に、本願の開示する情報処理装置、情報処理方法及びプログラムの実施例を図面に基づいて詳細に説明する。なお、実施例は開示の技術を限定するものではない。
【実施例１】
【００１２】
まず、実行履歴の採取について説明する。図１Ａ〜図１Ｇは、実行履歴の採取を説明するための図である。図１Ａにおいて、Ｎｕｌｌポインタエラーが発生するプログラムは、Ｊａｖａ（登録商標、以下同様）のバイトコードであり、「／／」に続く文字列はコメントである。プログラムはスタックを操作する複数のオペランド（命令）からなるリストである。オペランドには、スタック先頭にデータを挿入する読込命令、スタック先頭のデータを加工する演算命令等がある。
【００１３】
オペランドスタックは、オペランドにより操作されるスタックである。スロットは、データの一時的な記憶領域である。スロットは、例えば、レジスタにより実現される。ヒープは、動的に確保可能なメモリ領域である。オブジェクトはヒープに記録され、オペランドスタックとスロットでは、オブジェクトのアドレスが扱われる。ここで、「オブジェクトのアドレス」は、プログラム実行の一時点でオブジェクトを一意に識別する識別子である。
【００１４】
実行履歴は、採取される情報である。オペランド実行で使われるオブジェクトのアドレスと、そのオペランドの定義位置が実行履歴のデータとして採取される。オペランドの定義位置は、各オペランドの左の（）で囲まれた数字で表される。また、図１Ａ等において、太字で示される箇所は、対応するオペランドによって、参照、操作されるデータ、アドレス、フィールド名等である。
【００１５】
図１Ａに示すように、（０）ａｌｏａｄ＿０が実行され、スロット０番のアドレス値（Ａ９９９）がオペランドスタックの先頭に挿入される。ここで、「Ａ９９９」は、整数値「９９９」に変換されるアドレス値を表す。なお、図１Ａ等のコメントでは、「オペランドスタック」を単に「スタック」と表す。
【００１６】
そして、（１）ｇｅｔｆｉｅｌｄ  ＜ａｇｅ＞が実行され、オペランドスタックの先頭が指すオブジェクトのａｇｅフィールド値がオペランドスタックの先頭に挿入される。図１Ａでは、「３０」がオペランドスタックの先頭に挿入される。また、オブジェクトが使われたので、オペランドの定義位置（１）とオブジェクトのアドレス「Ａ９９９」が整数値に変換された値「９９９」とが採取される。
【００１７】
そして、（２）ａｌｏａｄ＿１が実行され、スロット１番のアドレス値（Ａ０、つまりＮｕｌｌ値）がオペランドスタックの先頭に挿入される。そして、（３）ｇｅｔｆｉｅｌｄ  ＜ａｇｅ＞が実行され、オペランドスタックの先頭が指すオブジェクトのアドレスが「Ａ０」であるので、ｎｕｌｌポインタエラーが発生する。また、オブジェクトが使われたので、オペランドの定義位置（３）とオブジェクトのアドレス「Ａ０」が整数値に変換された値「０」が採取される。
【００１８】
図１Ａに示す実行履歴を採取するためには、元のプログラムに実行履歴の採取用コードを挿入する必要がある。実行履歴の採取用コードが挿入されることによって元のプログラムから変換された変換後のプログラムを図１Ｂに示す。図１Ｂにおいて、定義位置（１）〜（３）のコード、定義位置（６）〜（８）のコード、定義位置（１１）〜（１６）のコードが元のプログラムに挿入されたコードである。なお、挿入されたコードの分だけ定義位置はずれる。定義位置（１）〜（３）、（６）〜（８）のコードは、オブジェクトのアドレスを整数に変換してスロットに一時的に記憶するためのコードである。（１１）〜（１６）のコードは、一時記憶したアドレスを書き出すコードであり、エラー発生時のみに実行される。
【００１９】
図１Ｂに示した変換後のプログラムは、図１Ｃ〜図１Ｇに示すように実行される。まず、図１Ｃに示すように、（０）ａｌｏａｄ＿０が実行され、スロット０番のアドレス値（Ａ９９９）がオペランドスタックの先頭に挿入される。そして、（１）ｄｕｐが実行され、オペランドスタックの先頭の値が複製される。図１Ｃでは、「Ａ９９９」が複製されている。そして、（２）ｉｎｖｏｋｅｓｔａｔｉｃ  ＜Ｓｙｓｔｅｍ．ｉｄｅｎｔｉｔｙＨａｓｈＣｏｄｅ（ｏｂｊｅｃｔ）＞が実行され、オペランドスタックの先頭のアドレス値（Ａ９９９）が整数値（９９９）に変換されてオペランドスタックの先頭に挿入される。
【００２０】
そして、図１Ｄに示すように、（３）ｉｓｔｏｒｅ＿２が実行され、オペランドスタックの先頭の整数値がスロット２番に記録される。そして、ｇｅｔｆｉｅｌｄ  ＜ａｇｅ＞が実行され、オペランドスタックの先頭が指すオブジェクトのａｇｅフィールド値がオペランドスタックの先頭に挿入される。図１Ｄでは、「３０」がオペランドスタックの先頭に挿入される。
【００２１】
そして、（５）ａｌｏａｄ＿１が実行され、スロット１番のアドレス値（Ａ０）がオペランドスタックの先頭に挿入される。そして、（６）ｄｕｐが実行され、オペランドスタックの先頭の値が複製される。図１Ｄでは、「Ａ０」が複製されている。
【００２２】
そして、図１Ｅに示すように、（７）ｉｎｖｏｋｅｓｔａｔｉｃ  ＜Ｓｙｓｔｅｍ．ｉｄｅｎｔｉｔｙＨａｓｈＣｏｄｅ（ｏｂｊｅｃｔ）＞が実行され、オペランドスタックの先頭のアドレス値（Ａ０）が整数値（０）に変換されてオペランドスタックの先頭に挿入される。そして、（８）ｉｓｔｏｒｅ＿３が実行され、オペランドスタックの先頭の整数値がスロット３番に記録される。そして、（９）ｇｅｔｆｉｅｌｄ  ＜ａｇｅ＞が実行され、オペランドスタックの先頭が指すオブジェクトのアドレスが「Ａ０」であるので、Ｎｕｌｌポインタエラーが発生する。
【００２３】
そして、エラーが発生したので、図１Ｆに示すように、（１１）ｓｉｐｕｓｈ  １が実行され、元の定義位置（１）を表す整数値の「１」がオペランドスタックの先頭に挿入される。そして、（１２）ｉｌｏａｄ＿２が実行され、スロット２番の整数値（９９９）がオペランドスタックの先頭に挿入される。そして、（１３）ｓｉｐｕｓｈ  ３が実行され、元の定義位置（３）を表す整数値の「３」がオペランドスタックの先頭に挿入される。そして、（１４）ｉｌｏａｄ＿３が実行され、スロット３番の整数値（０）がオペランドスタックの先頭に挿入される。
【００２４】
そして、図１Ｇに示すように、（１５）ｉｎｖｏｋｅｓｔａｔｉｃ  ＜Ｌｏｇｇｅｒ．ｗｒｉｔｅ（ｉｎｔ，ｉｎｔ，ｉｎｔ，ｉｎｔ）＞が実行され、オペランドスタックに積まれた４つの整数が実行履歴として書き出される。そして、（１６）ａｔｈｒｏｗが実行され、Ｎｕｌｌポインタエラーが再送出される。
【００２５】
このように、元のプログラムに実行履歴の採取用コードを挿入することによって、実行履歴が採取される。しかしながら、図１Ｂに示した変換後のプログラムには、オブジェクトのアドレスを整数に変換するコード（２）及び（７）の実行に時間がかかるという問題がある。図１Ａ〜図１Ｇに示したアドレス値「Ａ９９９」は整数値に変換されると「９９９」になるため、説明の便宜上アドレス値として「Ａ９９９」を用いた。しかしながら、アドレス値「Ａ９９９」から整数値「９９９」への変換は、例えば、ローカル変数への代入に要する時間と比較すると約１００倍の時間を要する。また、オブジェクトのアドレスを整数に変換するコード（２）及び（７）の実行は、エラーが発生しない場合には不要な実行である。
【００２６】
そこで、オブジェクトのアドレスを整数に変換する処理をエラー発生後に行うことが考えられる。ただし、オブジェクトは実行中に削除される可能性があり、オブジェクトが削除されると、オブジェクトのアドレスも消滅するため、エラー発生後にオブジェクトのアドレスを整数に変換することができなくなる。このため、オブジェクトのアドレスを強参照のまま一時的に記憶して、オブジェクトの削除を防ぐ必要がある。
【００２７】
しかしながら、オブジェクトのアドレスを強参照のまま保持し続けると、短命なオブジェクトでもガベージコレクション（Garbage  Collection）が行われなくなるため、メモリ使用量が余分にかかる。したがって、メモリ使用量を増加させずに実行時間の増加を防ぐことが必要となる。
【００２８】
そこで、実施例１に係る情報処理装置は、オブジェクトの生存期間に基づいて、オブジェクトのアドレスを整数に変換するタイミングを決定する。図２は、オブジェクトの生存期間を説明するための図である。図２において、スタックフレームとは、オペランドスタックとスロットの組であり、１メソッドの１実行状態を管理するものである。また、コールスタックとは、１スレッド上の複数メソッドの実行状態に対応する複数スタックフレームを管理するものである。図２は、ｍａｉｎメソッドがｔｅｓｔメソッドを呼び出し、ｔｅｓｔメソッドがｄｏＥｒｒｏｒメソッドを呼び出す場合を示し、ｄｏＥｒｒｏｒメソッド、ｔｅｓｔメソッドの実行状態に対応するスタックフレームを示す。
【００２９】
図２において、ｄｏＥｒｒｏｒ()オペランドスタックにあるアドレス「Ａ７７７」は、ｔｅｓｔ()のオペランドスタックにはなく、ｄｏＥｒｒｏｒからしか参照されていないため、ｄｏＥｒｒｏｒ実行中にガベージコレクションされる可能性がある。すなわち、アドレスが「Ａ７７７」であるオブジェクトは短命である。一方、ｄｏＥｒｒｏｒ()のオペランドスタックにあるアドレス「Ａ９９９」は、ｔｅｓｔ()のオペランドスタックにもあり、ｔｅｓｔからも参照されているため、ｄｏＥｒｒｏｒ実行中にガベージコレクションされることはない。すなわち、アドレスが「Ａ９９９」であるオブジェクトは長命である。
【００３０】
このように、メソッドの実行期間とオブジェクトの生存期間とは一致しない。特に、複数のスレッド、複数のスタックフレームから参照されているオブジェクトは、内側の多くのスタックフレームの生存期間すなわちメソッドの実行期間よりも長い間ガベージコレクションされずにヒープに生存し続ける可能性が高い。
【００３１】
そこで、実施例１に係る情報処理装置は、メソッドの実行期間よりも長命なオブジェクトはそのメソッド実行中にガベージコレクションされ得ないため、アドレス値を一時記憶してエラー発生後に整数値に変換する。また、実施例１に係る情報処理装置は、メソッドの実行期間よりも短命なオブジェクトはそのメソッド実行中にガベージコレクションされ得るため、アドレス値を整数値に変換してから一時記憶する。
【００３２】
図３は、実施例１に係る情報処理装置による処理の概要のフローを示すフローチャートである。図３に示すように、実施例１に係る情報処理装置は、メソッド実行期間よりも、オペランドが使用するオブジェクトの生存期間の方が長いか否かを判定する（ステップＳ１）。そして、実施例１に係る情報処理装置は、メソッド実行期間よりも、オペランドが使用するオブジェクトの生存期間の方が長い場合には、オペランドが使用するオブジェクトのアドレスを強参照のまま、実行履歴用に一時記憶する（ステップＳ２）。一方、実施例１に係る情報処理装置は、メソッド実行期間よりも、オペランドが使用するオブジェクトの生存期間の方が長くない場合には、オペランドが使用するオブジェクトのアドレスを整数値に変換してから、実行履歴用に一時記憶する（ステップＳ３）。
【００３３】
そして、実施例１に係る情報処理装置は、メソッド実行中にエラーが発生したか否か（ステップＳ４）に基づく処理を行う。すなわち、実施例１に係る情報処理装置は、メソッド実行中にエラーが発生した場合には、一時記憶した強参照は整数値に変換してから、一時記憶した整数値はそのまま実行履歴として外部出力する（ステップＳ５）。
【００３４】
このように、実施例１に係る情報処理装置は、メソッド実行期間とオブジェクトの生存期間とに基づいてオブジェクトのアドレスを整数値に変換するタイミングを変更することで、メモリ使用量を増加させずにＣＰＵ負荷を下げることができる。
【００３５】
図４は、実施例１に係る情報処理装置による処理例を説明するための図である。図４において、オペランドの元の定義位置が（１）であるオブジェクト（Ａ９９９）は、短命であり、オペランドの元の定義位置が（５）であるオブジェクト（Ａ２２２）は、長命であるとする。
【００３６】
図４の定義位置（２）及び（３）に示すように、オブジェクト（Ａ９９９）は短命であるので、アドレス値（Ａ９９９）は整数値に変換されて一時記憶される。一方、定義位置（９）に示すように、オブジェクト（Ａ２２２）は長命であるので、アドレス値（Ａ２２２）は整数値に変換されることなく一時記憶される。
【００３７】
そして、エラーが発生すると、短命であるオブジェクト（Ａ９９９）については、整数値が一時記憶されているので、定義位置（１５）に示すように、整数値（９９９）がオペランドスタックの先頭に挿入される。一方、長命であるオブジェクト（Ａ２２２）については、アドレス値が一時記憶されているので、定義位置（１８）に示すように、アドレス値（Ａ２２２）が整数値（２２２）に変換されてオペランドスタックの先頭に挿入される。
【００３８】
次に、実施例１に係る情報処理装置の構成について説明する。図５は、実施例１に係る情報処理装置の構成を示す図である。図５に示すように、実施例１に係る情報処理装置１は、ＣＰＵ２（Central  Processing  Unit）と、メインメモリ３と、入出力Ｉ／Ｆ４と、入出力装置４ａと、Ｒ／Ｗ部５と、プログラム記憶媒体５ａと、ネットワークＩ／Ｆ６と、記憶部７とを有する。ＣＰＵ２、メインメモリ３、入出力Ｉ／Ｆ４、Ｒ／Ｗ部５、ネットワークＩ／Ｆ６及び記憶部７は、バス８によって接続される。
【００３９】
ＣＰＵ２は、メインメモリ３からプログラムを読み出して実行する中央処理装置である。メインメモリ３は、プログラムやプログラムの実行途中結果などを記憶するメモリである。入出力Ｉ／Ｆ４は、入出力装置４ａとＣＰＵ２を接続するインタフェースである。入出力装置４ａは、マウス、キーボード、液晶表示装置等の入出力を行うための装置である。
【００４０】
Ｒ／Ｗ部５は、プログラム記憶媒体５ａからの読み出し、プログラム記憶媒体５ａへの書き込みを行う装置である。プログラム記憶媒体５ａは、ＤＶＤ、ＣＤ、ＵＳＢメモリ等の記憶媒体である。ネットワークＩ／Ｆ６は、情報処理装置１をネットワーク経由で他の情報処理装置等に接続するためのインタフェースである。
【００４１】
記憶部７は、プログラムやデータを格納する装置であり、ＨＤＤ（Hard  Disk  Drive）、ＳＳＤ（Solid  State  Drive）等である。記憶部７は、システムプログラム１０とアプリケーションプログラム２０とを記憶する。また、記憶部７は、データを記憶する情報記憶領域３０を有する。
【００４２】
情報処理装置１において実行されるプログラムは、プログラム記憶媒体５ａに記憶され、Ｒ／Ｗ部５によってプログラム記憶媒体５ａから読み出されて情報処理装置１にインストールされる。あるいは、情報処理装置１において実行されるプログラムは、ネットワークＩ／Ｆ６を介して接続された他の情報処理システムのデータベース等に記憶され、これらのデータベースから読み出されて情報処理装置１にインストールされる。そして、インストールされたプログラムは、記憶部７に記憶され、メインメモリ３に読み出されてＣＰＵ２によって実行される。
【００４３】
情報記憶領域３０には、オブジェクトの生存期間の予測結果と、プログラムが実行された際に採取された実行履歴が記憶される。実行履歴には、オペランド実行で使われるオブジェクトのアドレスと、そのオペランドの定義位置が含まれる。
【００４４】
アプリケーションプログラム２０には、バイトコードが含まれる。バイトコードは、バイトコード実行部１４により実行される。
【００４５】
システムプログラム１０は、アプリケーションプログラム２０を実行するために必要なソフトウェアである。システムプログラム１０は、バイトコードを実行して実行履歴を採取する機能を有する。図６は、バイトコードを実行して実行履歴を採取する機能に関して、システムプログラム１０の機能構成を示す図である。
【００４６】
図６に示すように、システムプログラム１０は、採取コード挿入部１１と、予測コード挿入部１２と、バイトコード変換部１３と、バイトコード実行部１４と、生存期間予測部１５と、実行履歴出力部１６と、記憶部１７とを有する。
【００４７】
採取コード挿入部１１は、実行履歴が採取されるプログラムに実行履歴を採取するためのコードを挿入する。予測コード挿入部１２は、実行履歴が採取されるプログラムにオブジェクトの生存期間を予測するためのコードを挿入する。
【００４８】
採取コード挿入部１１は、オブジェクトの生存期間の予測結果に基づいて、オブジェクトのアドレスを整数値に変換するコードを挿入する箇所を切り替える。すなわち、採取コード挿入部１１は、オブジェクトの生存期間がメソッド実行期間よりも長い場合には、エラー発生時に行う処理の中にオブジェクトのアドレスを整数値に変換するコードを挿入する。一方、オブジェクトの生存期間がメソッド実行期間よりも短い場合には、採取コード挿入部１１は、オブジェクトが使用された箇所にオブジェクトのアドレスを整数値に変換するコードを挿入する。
【００４９】
バイトコード変換部１３は、プログラムをバイトコードに変換する。バイトコード実行部１４は、バイトコードを実行する。
【００５０】
生存期間予測部１５は、予測コード挿入部１２により挿入されたコードを実行することにより、オブジェクトの生存期間を予測し、予測結果を出力する。オブジェクトには、使用時刻とガベージコレクションによる回収時刻が記録されたタグが付加され、生存期間予測部１５は、タグを用いてオブジェクトの生存期間を予測する。
【００５１】
図７は、オブジェクトの使用時刻及び回収時刻を記録する処理の一例を説明するための図である。図７に示すように、ＪＶＭ（Java  Virtual  Machine）４１のＣｌａｓｓＬｏａｄｅｒ４２は、クラスファイル４０を読み込んで（１）、Ｐｒｅｄｉｃｔｏｒ４３に渡す（２）。Ｐｒｅｄｉｃｔｏｒ４３は、ｐｒｅｄｉｃｔ()を呼び出すコードをクラスファイル４０に挿入し、クラスファイル４０をＣｌａｓｓＬｏａｄｅｒ４２に戻す（３）。
【００５２】
そして、クラスファイル４０のクラスがＪａｖａプログラムとして実行され（４）、オブジェクトの使用が開始されると（５）、ｐｒｅｄｉｃｔ()が呼び出され（６）、Ｐｒｅｄｉｃｔｏｒ４３が呼出元と使用時刻を記録し（７）、呼出元と使用時刻を記録したタグを生成する（８）。
【００５３】
そして、ＪＶＭＴＩ（ＪＶＭ  Tool  Interface）４４がオブジェクトにタグを付与し（９）、ＧＣ４５がオブジェクトを回収するとタグをＪＶＭＴＩ４４に渡す（１０〜１１）。そして、ＪＶＭＴＩ４４は、タグに回収時刻を記録し、使用時刻と回収時刻をファイルに出力する（１２）。オブジェクトの生存期間は、使用時刻と回収時刻から算出される。
【００５４】
なお、タグ付けと回収時刻記録の実行有無を、確率的に間引く（サンプリングする）ことで、記録にかかる負荷の大きさは調整することができる。
【００５５】
実行履歴出力部１６は、採取コード挿入部１１により挿入されたコードを実行することにより実行履歴データを採取して実行履歴を出力する。記憶部１７は、バイトコードを実行して実行履歴を採取する機能に関連する情報を記憶する。記憶部１７は、予測結果記憶部１７ａと、実行履歴記憶部１７ｂと、バイトコード記憶部１７ｃとを有する。
【００５６】
予測結果記憶部１７ａは、予測結果を記憶する。図８は、予測結果記憶部１７ａの一例を示す図である。図８に示すように、予測結果記憶部１７ａは、クラス名と、メソッド定義と、元定義位置と、生存期間とをオブジェクト毎に対応付けて記憶する。
【００５７】
クラス名は、オブジェクトが属するクラスの名前である。メソッド定義は、オブジェクトが使用されるメソッドの名前である。元定義位置は、オブジェクトが使用されるオペランドの元の定義位置である。生存期間は、オブジェクトの生存期間である。例えば、「ＴａｒｇｅｔＣｌａｓｓ」に属し、「ｇｅｔＡｇｅ」で使用され、実行履歴の採取用コードが挿入される前の定義位置が（１）であるオブジェクトの生存期間は「１０秒間」である。
【００５８】
実行履歴記憶部１７ｂは、実行履歴を記憶する。図９は、実行履歴記憶部１７ｂの一例を示す図である。図９に示すように、実行履歴記憶部１７ｂは、クラス名と、メソッド定義と、元定義位置と、アドレスと、時刻とを実行履歴データ毎に記憶する。
【００５９】
クラス名は、オブジェクトが属するクラスの名前である。メソッド定義は、オブジェクトが使用されたメソッドの名前である。元定義位置は、オブジェクトが使用されるオペランドの元の定義位置である。アドレスは、オブジェクトのアドレスから変換された整数値である。時刻は、データが採取された時刻である。例えば、「ＴａｒｇｅｔＣｌａｓｓ」に属し、「ｇｅｔＡｇｅ」で使用され、実行履歴の採取用コードが挿入される前の定義位置が（１）であるオブジェクトのアドレスは整数値に変換されると「９９９」であり、採取時刻は「１５：２１」である。
【００６０】
バイトコード記憶部１７ｃは、バイトコードを記憶する。図１０は、バイトコード記憶部１７ｃの一例を示す図である。図１０に示すように、バイトコード記憶部１７ｃは、完全パスと、元バイトコードと、採取用バイトコードと、予測用バイトコードを記憶する。
【００６１】
完全パスは、バイトコードが格納された場所へのパスである。元バイトコードは、元のバイトコードすなわち実行履歴が採取されるバイトコードである。採取用バイトコードは、実行履歴を採取するためのコードが挿入されたバイトコードである。予測用バイトコードは、オブジェクトの生存期間を予測するためのコードが挿入されたバイトコードである。予測用バイトコードの（２）ｉｎｖｏｋｅｓｔａｔｉｃ  <Ｐｒｅｄｉｃｔｏｒ．ｐｒｅｄｉｃｔ（Ｏｂｊｅｃｔ）>によって、使用時刻が記録されたタグが生成される。
【００６２】
次に、情報処理装置１による処理のフローについて説明する。図１１は、情報処理装置１による処理のフローを示すフローチャートである。図１１に示すように、情報処理装置１は、元のバイトコードにオブジェクトの生存期間を予測するコードを挿入し、予測用バイトコードとして保存する（ステップＳ１１）。
【００６３】
そして、情報処理装置１は、予測用バイトコードを実行し、オブジェクト生存期間の予測結果を記録する（ステップＳ１２）。そして、情報処理装置１は、オブジェクト生存期間の予測結果に基づいて、元のバイトコードに実行履歴の採取用コードを挿入し、採取用バイトコードとして保存する（ステップＳ１３）。そして、情報処理装置１は、採取用バイトコードを実行し、実行履歴を記録する（ステップＳ１４）。
【００６４】
このように、情報処理装置１は、予測用バイトコードを実行してオブジェクト生存期間を予測することによって、オブジェクト生存期間に基づく採取用コードの挿入を行うことができる。
【００６５】
図１２は、ステップＳ１１の処理のフローを示すフローチャートである。図１２に示すように、予測コード挿入部１２は、オペランドａはオブジェクトを使用するか否かを判定する（ステップＳ１１１）。そして、予測コード挿入部１２は、オペランドａがオブジェクトを使用する場合には、オペランドａが使用するオブジェクトの使用時刻及び回収時刻を記録するためのコードを、オペランドａの手前に挿入する（ステップＳ１１２）。なお、予測コード挿入部１２は、図１２に示す処理を元のバイトコードの各オペランドに対して行う。
【００６６】
図１３は、ステップＳ１２の処理のフローを示すフローチャートである。図１３に示すように、生存期間予測部１５は、メソッドｍの実行中に、オペランドａの実行前に渡されたオブジェクトｂに、ＪＶＭＴＩ４４のタグを付与する（ステップＳ１２１）。すると、ＧＣ４５によるオブジェクト回収時にイベント通知が行われる。
【００６７】
そして、オブジェクトｂがガベージコレクションされると、ＪＶＴＭＩのＯｂｊｅｃｔＦｒｅｅイベントが通知されるので、生存期間予測部１５は、その時の時刻をオブジェクトｂの回収時刻として記録する（ステップＳ１２２）。そして、生存期間予測部１５は、オブジェクトｂの回収時刻は、メソッドｍの実行終了時刻よりも後であるか否かを判定する（ステップＳ１２３）。
【００６８】
そして、オブジェクトｂの回収時刻がメソッドｍの実行終了時刻よりも後である場合には、生存期間予測部１５は、メソッドｍのオペランドａが使用するオブジェクトの生存期間は「長命」であると記録する（ステップＳ１２４）。一方、オブジェクトｂの回収時刻がメソッドｍの実行終了時刻よりも後でない場合には、生存期間予測部１５は、メソッドｍのオペランドａが使用するオブジェクトの生存期間は「短命」であると記録する（ステップＳ１２５）。
【００６９】
図１４は、ステップＳ１３の処理のフローを示すフローチャートである。図１４に示すように、採取コード挿入部１１は、メソッドｍのオペランドａが使用するオブジェクトｂは「長命」だと記録されているか否かを判定する（ステップＳ１３１）。
【００７０】
そして、「長命」だと記録されている場合には、採取コード挿入部１１は、オブジェクトｂのアドレスを強参照のまま実行履歴用に一時記憶するコードを、オペランドａの手前に挿入する（ステップＳ１３２）。一方、「短命」だと記録されている場合には、採取コード挿入部１１は、オブジェクトｂのアドレスを整数値に変換してから実行履歴用に一時記憶するコードを、オペランドａの手前に挿入する（ステップＳ１３３）。なお、採取コード挿入部１１は、図１４に示す処理を元のバイトコードの各オペランドに対して行う。
【００７１】
図１５は、ステップＳ１４の処理のフローを示すフローチャートである。図１５に示すように、実行履歴出力部１６は、メソッドｍのオペランドａが使用するオブジェクトｂの生存期間が「長命」であるか否か（ステップＳ１４１）に基づく処理を行う。すなわち、実行履歴出力部１６は、メソッドｍのオペランドａが使用するオブジェクトｂの生存期間が「長命」である場合には、オペランドａが使用するオブジェクトｂのアドレスを強参照のまま実行履歴用に一時記憶する（ステップＳ１４２）。一方、実行履歴出力部１６は、メソッドｍのオペランドａが使用するオブジェクトｂの生存期間が「長命」でない場合には、オペランドａが使用するオブジェクトｂのアドレスを整数値に変換してから実行履歴用に一時記憶する（ステップＳ１４３）。
【００７２】
そして、実行履歴出力部１６は、メソッド実行中にエラーが発生したか否か（ステップＳ１４４）に基づく処理を行う。すなわち、実行履歴出力部１６は、メソッド実行中にエラーが発生した場合には、一時記憶した強参照は整数値に変換してから、一時記憶した整数値はそのまま、実行履歴として外部出力する（ステップＳ１４５）。
【００７３】
次に、情報処理装置１による処理例について図１６〜図２０を用いて説明する。図１６は、処理例の説明に用いられる実行状態の文字列表現を説明するための図である。図１６（ａ）は、オペランドスタック、スロット及びヒープの文字列表現例を示し、図１６（ｂ）は、バイトコード実行後の実行状態の文字列表現例を示す。
【００７４】
図１６（ａ）に示すように、Ｓｔａｃｋ［Ａ９９９，Ａ１１１］は、オペランドスタックに「Ａ１１１」と「Ａ９９９」が積まれていることを表す。Ｓｌｏｔ［０：Ａ９９９，１：Ａ０，２：Ａ１１１］は、スロットの０番地が「Ａ９９９」を記憶し、１番地が「Ａ０」を記憶し、２番地が「Ａ１１１」を記憶することを表す。
【００７５】
Ｈｅａｐ［９９９：｛ａｇｅ：３０，ｂｌｏｏｄ：Ａ｝，１１１：｛ａｇｅ：６２｝］は、ヒープが、整数値「９９９」で識別されるオブジェクトと、整数値「１１１」で識別されるオブジェクトを記憶することを表す。また、整数値「９９９」で識別されるオブジェクトのａｇｅフィールド値が「３０」であり、ｂｌｏｏｄフィールド値が「Ａ」であり、整数値「１１１」で識別されるオブジェクトのａｇｅフィールド値が「６２」であることを表す。
【００７６】
また、図１６（ｂ）は、ｇｅｔｆｉｅｌｄ  ＜ａｇｅ＞を実行後のオペランドスタック、スロット及びヒープの状態を表す。
【００７７】
図１７は、変換前のバイトコードを示す図である。図１７は、ａｇｅフィールドを持つＰｅｒｓｏｎ型のオブジェクトを２つ引数として受け取り、一方のａｇｅフィールド値を、もう一方のａｇｅフィールド値で除算するプログラムを示す。割る数が０の場合、ゼロ除算エラーが発生し、メソッド実行が終了する。なお、アドレス「Ａ９９９」のオブジェクトは短命で、アドレス「Ａ１１１」のオブジェクトは長命であるとする。すなわち、ガベージコレクションが実行されると、アドレス「Ａ９９９」のオブジェクトは回収される。
【００７８】
図１７に示すように、定義位置（３）と（４）の間でガベージコレクションが実行されると、ヒープから整数値「９９９」で識別されるオブジェクトが削除される。また、定義位置（８）において、「３０÷０」が実行され、ゼロ除算エラーが発生する。
【００７９】
図１８は、予測用バイトコードを示す図である。図１８の定義位置（０）と（１）の間及び定義位置（４）と（５）の間に示すように、オブジェクトがオペランドスタックに積まれた直後に、ｄｕｐ命令で複製されたオブジェクトアドレスを引数としてＰｒｅｄｉｃｔｏｒ．ｐｒｅｄｉｃｔ（ｏｂｊｅｃｔ）メソッドが呼び出される。すると、引数のオブジェクトにＪＶＭＴＩ４４のタグが付与され、その時の時刻（使用時刻）が記録される。また、定義位置（３）と（４）の間に示すように、タグが付与されたオブジェクトがガベージコレクションされる。すると、ＪＶＭＴＩ４４のＯｂｊｅｃｔＦｒｅｅイベントが通知されるので、その時の時刻（回収時刻）と使用時刻との差が、オブジェクトの生存期間として記録される。
【００８０】
この例では、定義位置（０）で使用されたオブジェクト（アドレス「Ａ９９９」のオブジェクト）の生存期間は「１秒間」であり、定義位置（４）で使用されたオブジェクト（アドレス「Ａ２２２」のオブジェクト）の生存期間は「３６００秒間」である。ここでは、メソッド実行時間の代わりに閾値を「５秒間」として閾値に基づいてオブジェクトが短命であるか長命であるかを決定するとすると、定義位置（０）で使用されたオブジェクトは短命であり、定義位置（４）で使用されたオブジェクトは長命である。
【００８１】
図１９は、採取用のバイトコードを示す図である。図１９に示すように、定義位置（０）のオブジェクトは短命のため、ガベージコレクションを阻害しないよう、オブジェクトのアドレスは整数値に変換される。一方、定義位置（４）のオブジェクトは長命のため、ＣＰＵ負荷を減らすべく、オブジェクトのアドレスは強参照で保持される。そして、定義位置（４）のオブジェクトのアドレスは、エラー発生時に整数値に変換される。
【００８２】
図２０は、採取された実行履歴を示す図である。図２０に示すように、定義位置（０）で使用されたオブジェクトのアドレスの整数値「９９９」と定義位置（４）で使用されたオブジェクトのアドレスの整数値「２２２」が実行履歴に記録される。
【００８３】
この処理例では、定義位置（４）で使用されたオブジェクトのアドレスを整数値に変換する処理が、エラーが発生しない正常動作時にも都度実施する場合と比較すると、約９９ＣＰＵクロック分ＣＰＵ負荷が減少する。
【００８４】
上述してきたように、実施例１では、予測コード挿入部１２がオブジェクトの生存期間を予測するためのコードを挿入し、生存期間予測部１５が、予測コード挿入部１２により挿入されたコードに基づいて、オブジェクトの生存期間を予測する。そして、オブジェクトの生存期間に基づいて、採取コード挿入部１１が、実行履歴を記録するためのコードを切り替えて挿入し、実行履歴出力部１６が、採取コード挿入部１１により挿入されたコードに基づいて、実行履歴を出力する。したがって、情報処理装置１は、メモリ使用量を増加させずに実行時間の増加を防ぐことができる。
【００８５】
また、実施例１では、生存期間予測部１５は、メソッドの実行時間よりもオブジェクトの生存期間が長い場合には、オブジェクトの生存期間を長命と予測し、メソッドの実行時間よりもオブジェクトの生存期間が長くない場合には、オブジェクトの生存期間を短命と予測する。したがって、生存期間予測部１５は、オブジェクトの生存期間を適切に予測することができる。
【００８６】
また、実施例１では、例えば、生存期間予測部１５は、所定の閾値よりもオブジェクトの生存期間が長い場合には、オブジェクトの生存期間を長命と予測し、所定の閾値よりもオブジェクトの生存期間が長くない場合には、オブジェクトの生存期間を短命と予測する。したがって、生存期間予測部１５は、オブジェクトの生存期間を適切に予測することができる。
【実施例２】
【００８７】
ところで、上記実施例１では、オブジェクトの生存期間を１度だけ予測して実行履歴を採取する場合について説明したが、オブジェクトの生存期間の予測結果は変わることがある。そこで、実施例２では、オブジェクトの変化する生存期間の予測結果に応じて、実行履歴を記録するためのコードを再挿入する情報処理装置１について説明する。
【００８８】
図２１は、実施例２に係る情報処理装置１による処理のフローを示すフローチャートである。図２１に示すように、実施例２に係る情報処理装置１は、元のバイトコードにオブジェクトの生存期間を予測するコードを挿入し、予測用バイトコードとして保存する（ステップＳ２１）。
【００８９】
そして、実施例２に係る情報処理装置１は、オブジェクト生存期間の予測結果が全て長命であるとして、元のバイトコードに実行履歴の採取用コードを挿入し、採取用バイトコードとして保存する（ステップＳ２２）。そして、実施例２に係る情報処理装置１は、予測用バイトコードを実行し、オブジェクト生存期間の予測結果を記録する（ステップＳ２３）。
【００９０】
そして、実施例２に係る情報処理装置１は、予測結果（長命又は短命）が変化したオブジェクトがあるか否かを判定し（ステップＳ２４）、変化したオブジェクトがない場合には、ステップＳ２３に戻る。
【００９１】
一方、変化したオブジェクトがある場合には、実施例２に係る情報処理装置１は、オブジェクト生存期間の予測結果に基づいて、元のバイトコードに実行履歴の採取用コードを挿入し、採取用バイトコードとして保存する（ステップＳ２５）。そして、実施例２に係る情報処理装置１は、採取用バイトコードを実行し、実行履歴を記録し（ステップＳ２６）、ステップＳ２３に戻る。
【００９２】
このように、実施例２に係る情報処理装置１は、オブジェクトの生存期間の予測と履歴採取を同時実行する。そして、実施例２に係る情報処理装置１は、オブジェクトの変化する生存期間の予測結果に応じて、実行履歴の採取用コードを挿入することによって、オブジェクトの生存期間が変化する場合に対応することができる。
【００９３】
図２２は、オブジェクト生存期間の予測結果が全て長命であるとして実行履歴の採取用コードが挿入された採取用バイトコードを示す図である。図２２に示すように、予測結果がない間は、定義位置（０）及び定義位置（４）の両方でオブジェクトのアドレスを強参照のまま保持する。
【００９４】
図２３は、オブジェクト生存期間の予測結果に基づいて実行履歴の採取用コードが再挿入された採取用バイトコードを示す図である。なお、ここでは、定義位置（０）で使用されたオブジェクトが短命であると予測された場合を示す。図２３を図２２と比較すると、定義位置（０）で使用されたオブジェクトのアドレスを整数値に変換するコードｉｎｖｏｋｅｓｔａｔｉｃ  ＜Ｓｙｓｔｅｍ．ｉｄｅｎｔｉｔｙＨａｓｈＣｏｄｅ（ｏｂｊｅｃｔ）＞が定義位置（１０）の後から定義位置（０）の後へ移動されている。
【００９５】
上述してきたように、実施例２に係る情報処理装置１は、オブジェクトの生存期間の予測結果が変化すると、実行履歴の採取用コードを再挿入することによって、オブジェクトの生存期間が変化する場合にも対応することができる。
【実施例３】
【００９６】
上記実施例１及び実施例２では、オブジェクトの生存期間に基づいて実行履歴の採取用コードを切り替える場合について説明したが、実行履歴の採取用コードを実行時に切り替えることもできる。そこで、実施例３では、実行履歴の採取用コードを実行時に切り替える情報処理装置１について説明する。
【００９７】
実施例３に係る情報処理装置１は、予測用コードと採取用コードの両方を作成する。その際、実施例３に係る情報処理装置１は、オブジェクトのアドレスを整数変換するコードと強参照で一時保持するコードの両方を採取用コードに挿入しておく。そして、実施例３に係る情報処理装置１は、ヒープに生存期間の予測結果を格納しておき、採取用コードが予測結果を都度参照してコードを切り替える。
【００９８】
図２４は、予測結果を実行履歴採取時に参照する方法を説明するための図である。図２４では、ヒープの整数値「５５５」で識別されるオブジェクトのｃｏｄｅ＿４フィールドに予測結果が格納されている。オブジェクトの生存期間が短命である場合には、ｃｏｄｅ＿４フィールドの値は「０」であり、長命である場合には、ｃｏｄｅ＿４フィールドの値は「１」である。
【００９９】
Ｐｒｅｄｉｃｔｏｒクラスのフィールドがアドレス「Ａ５５５」を介して参照できる実行状態では、ＧＥＴＳＴＡＴＩＣ  ＜Ｐｒｅｄｉｃｔｏｒ．ｃｏｄｅ＿４＞（クラス変数の参照命令）の実行により、オペランドスタックのトップに「１」が積まれる。そして、ｉｆｎｅ  ＄｛ジャンプ先のラベル｝の実行により、オペレランドスタックのトップの値が１の場合に、ジャンプ先のラベルまで処理をスキップすることで、実行するコードを切り替えることができる。
【０１００】
図２５は、実施例３に係る情報処理装置１による処理のフローを示すフローチャートである。図２５に示すように、実施例３に係る情報処理装置１は、元のバイトコードにオブジェクトの生存期間を予測するコードを挿入し、予測用バイトコードとして保存する（ステップＳ３１）。
【０１０１】
そして、実施例３に係る情報処理装置１は、元のバイトコードに、長命用と短命用の実行履歴の採取用コードをどちらも挿入する（ステップＳ３２）。そして、実施例３に係る情報処理装置１は、コード実行時のオブジェクト生存期間の予測結果に基づいて動的に（コードとして挿入したｉｆ文により）長命用と短命用の採取用コードのどちらかを実行するコードを挿入する（ステップＳ３３）。
【０１０２】
そして、実施例３に係る情報処理装置１は、予測用バイトコードを実行し、オブジェクト生存期間の予測結果を記録する（ステップＳ３４）。そして、実施例３に係る情報処理装置１は、現時点の予測結果は長命であるか否かを判定し（ステップＳ３５）、長命である場合には、長命用の採取用コードを実行し、実行履歴を記録する（ステップＳ３６）。そして、実施例３に係る情報処理装置１は、ステップＳ３４に戻る。
【０１０３】
一方、現時点の予測結果が長命でない場合には、実施例３に係る情報処理装置１は、短命用の採取用コードを実行し、実行履歴を記録する（ステップＳ３７）。そして、実施例３に係る情報処理装置１は、ステップＳ３４に戻る。
【０１０４】
上述してきたように、実施例３に係る情報処理装置１は、長命用と短命用のコードのどちらかを実行するコードを挿入し、オブジェクトの生存期間の実行時の予測結果に基づいて、長命用と短命用のコードのどちらかを実行する。したがって、実施例３に係る情報処理装置１は、オブジェクトの生存期間が変化する場合にも対応することができる。
【実施例４】
【０１０５】
実施例３では、オブジェクトの生存期間が変化する場合に対応して実行履歴の採取を繰り返す場合について説明したが、オブジェクトの生存期間を１度だけ予測する場合にも、実行履歴の採取時に長命用と短命用のコードのどちらかを実行してもよい。そこで、実施例４では、オブジェクトの生存期間を１度だけ予測し、実行履歴の採取時に長命用と短命用のコードのどちらかを実行する場合について説明する。
【０１０６】
実施例４に係る情報処理装置１は、オブジェクトのアドレスを整数変換するコードと強参照で一時保持するコードの両方を採取用コードに挿入しておく。また、実施例４に係る情報処理装置１は、実施例３と同様な方法で予測結果を参照し、採取用コードが実行時にコードを切り替える。
【０１０７】
図２６は、実施例４に係る情報処理装置１による処理のフローを示すフローチャートである。図２６に示すように、実施例４に係る情報処理装置１は、元のバイトコードにオブジェクトの生存期間を予測するコードを挿入し、予測用バイトコードとして保存する（ステップＳ４１）。
【０１０８】
そして、実施例４に係る情報処理装置１は、元のバイトコードに、長命用と短命用の実行履歴の採取用コードをどちらも挿入する（ステップＳ４２）。そして、実施例４に係る情報処理装置１は、コード実行時のオブジェクト生存期間の予測結果に基づいて動的に（コードとして挿入したｉｆ文により）長命用と短命用の採取用コードのどちらかを実行するコードを挿入する（ステップＳ４３）。
【０１０９】
そして、実施例４に係る情報処理装置１は、予測用バイトコードを実行し、オブジェクト生存期間の予測結果を記録する（ステップＳ４４）。そして、実施例４に係る情報処理装置１は、現時点の予測結果は長命であるか否かを判定し（ステップＳ４５）、長命である場合には、長命用の採取用コードを実行し、実行履歴を記録する（ステップＳ４６）。一方、現時点の予測結果が長命でない場合には、実施例４に係る情報処理装置１は、短命用の採取用コードを実行し、実行履歴を記録する（ステップＳ４７）。
【０１１０】
上述してきたように、実施例４に係る情報処理装置１は、長命用と短命用のコードのどちらかを実行するコードを挿入し、オブジェクトの生存期間の１回の予測結果に基づいて、長命用と短命用のコードのどちらかを実行する。したがって、実施例４に係る情報処理装置１は、実行履歴を採取するコードの挿入時にコードを切り替えることなく、採取用コードを生成することができる。
【０１１１】
なお、実施例では、Ｊａｖａプログラムの実行履歴を採取する場合について説明したが、本発明はこれに限定されるものではなく、Ｃｅｙｌｏｎ等の他のオブジェクト指向言語で作成されたプログラムにも同様に適用することができる。
【符号の説明】
【０１１２】
１    情報処理装置
２    ＣＰＵ
３    メインメモリ
４    入出力Ｉ／Ｆ
４ａ    入出力装置
５    Ｒ／Ｗ部
５ａ    プログラム記憶媒体
６    ネットワークＩ／Ｆ
７    記憶部
８    バス
１０    システムプログラム
１１    採取コード挿入部
１２    予測コード挿入部
１３    バイトコード変換部
１４    バイトコード実行部
１５    生存期間予測部
１６    実行履歴出力部
１７    記憶部
１７ａ    予測結果記憶部
１７ｂ    実行履歴記憶部
１７ｃ    バイトコード記憶部
２０    アプリケーションプログラム
３０    情報記憶領域
４１    ＪＶＭ
４０    クラスファイル
４２    ＣｌａｓｓＬｏａｄｅｒ
４３    Ｐｒｅｄｉｃｔｏｒ
４４    ＪＶＭＴＩ
４５    ＧＣ
【図１Ａ】
2018097817.tif 000003
【図１Ｂ】
2018097817.tif 000004
【図１Ｃ】
2018097817.tif 000005
【図１Ｄ】
2018097817.tif 000006
【図１Ｅ】
2018097817.tif 000007
【図１Ｆ】
2018097817.tif 000008
【図１Ｇ】
2018097817.tif 000009
【図２】
2018097817.tif 000010
【図３】
2018097817.tif 000011
【図４】
2018097817.tif 000012
【図５】
2018097817.tif 000013
【図６】
2018097817.tif 000014
【図７】
2018097817.tif 000015
【図８】
2018097817.tif 000016
【図９】
2018097817.tif 000017
【図１０】
2018097817.tif 000018
【図１１】
2018097817.tif 000019
【図１２】
2018097817.tif 000020
【図１３】
2018097817.tif 000021
【図１４】
2018097817.tif 000022
【図１５】
2018097817.tif 000023
【図１６】
2018097817.tif 000024
【図１７】
2018097817.tif 000025
【図１８】
2018097817.tif 000026
【図１９】
2018097817.tif 000027
【図２０】
2018097817.tif 000028
【図２１】
2018097817.tif 000029
【図２２】
2018097817.tif 000030
【図２３】
2018097817.tif 000031
【図２４】
2018097817.tif 000032
【図２５】
2018097817.tif 000033
【図２６】
2018097817.tif 000034