(57)【要約】【課題】オブジェクトのプログラム中の割り付け場所をメモリ内のヒープ領域の実行時オブジェクトから効率的に追跡する方法が求められている。【解決手段】本発明は、ハッシュ値フィールドを有する実行時オブジェクトを実装するためのプログラム中のオブジェクトの割り付け場所を、該実行時オブジェクトから追跡することを可能にするための該実行時オブジェクトのデータ構造を提供する。本発明はまた、該プログラム中のオブジェクトの割り付け場所を、該実行時オブジェクトから追跡するための方法、そのコンピュータ・システム及びコンピュータ・プログラムを提供する。【選択図】図２Ａ
2010204955.tif 000002
【特許請求の範囲】
【請求項１】
ハッシュ値フィールドを有する実行時オブジェクトを実装するためのプログラム中のオブジェクトの割り付け場所を、該実行時オブジェクトから追跡することを可能にするための該実行時オブジェクトのデータ構造であって、
前記実行時オブジェクトのハッシュ値フィールドがハッシュ値として前記割り付け場所に対応した値とオブジェクト識別子とを含み、前記追跡が該値に対応する前記オブジェクトの割り付け場所を特定することによって行われる、前記データ構造。
【請求項２】
ハッシュ値フィールドを有する実行時オブジェクトを実装するためのプログラム中のオブジェクトの割り付け場所を、該実行時オブジェクトから追跡するための方法であって、
請求項１に記載のデータ構造から前記割り付け場所に対応した値を取得するステップと、
前記取得した値に対応する前記オブジェクトの割り付け場所を特定するステップと
を含む、前記方法。
【請求項３】
前記特定が、
ハッシュ値が参照されたことのある実行時オブジェクトのハッシュ値フィールドに含まれる前記値（以下、第１の値）と該第１の値に対応する割り付け場所を特定するための情報との対応付けを記録する対応表（以下、第１の対応表）から、前記第１の値に対応する割り付け場所を特定することによって行われる、請求項２に記載の方法。
【請求項４】
前記第１の値が、該第１の値を含む前記実行時オブジェクトのハッシュ値が参照されることに応じて求められる値である、請求項３に記載の方法。
【請求項５】
前記第１の値が、二分木構造によって求められる値である、請求項４に記載の方法。
【請求項６】
前記二分木構造が前記第１の値と該第１の値に対応する割り付け場所との対応関係を示し、並びに前記二分木構造の枝が前記第１の値のビット表示の各ビットを示し、及び前記二分木構造のノードが前記オブジェクトの割り付け場所を示す、請求項５に記載の方法。
【請求項７】
前記特定が、
ハッシュ値が参照されたことのない実行時オブジェクトのハッシュ値フィールドに含まれる前記値（以下、第２の値）と該第２の値に対応する割り付け場所との対応付けを記録する対応表（以下、第２の対応表）から、前記第２の値に対応する割り付け場所を特定することによって行われる、請求項２に記載の方法。
【請求項８】
ハッシュ値フィールドを有する実行時オブジェクトを実装するためのプログラム中のオブジェクトの割り付け場所を、該実行時オブジェクトから追跡することを可能にする方法であって、
前記実行時オブジェクトのメモリへの割り付けに応じて、
請求項１に記載のデータ構造の前記ハッシュ値フィールド内に、前記プログラム中のオブジェクトの前記割り付け場所に対応した値を埋め込むステップを含み、前記ハッシュ値フィールドがハッシュ値として前記埋め込まれた値とオブジェクト識別子とを含み、前記追跡が該埋め込まれた値に対応する前記オブジェクトの割り付け場所を特定することによって行われる、
前記方法。
【請求項９】
前記実行時オブジェクトのハッシュ値の参照命令が実行されることに応じて、
前記埋め込まれた値を、計算された値に置き換えるステップと、
前記計算された値と前記埋め込まれた値との対応表をメモリ内に作成するステップと
をさらに含む、請求項８に記載の方法。
【請求項１０】
前記プログラム中のオブジェクトの割り付け場所が同一である実行時オブジェクトが多くメモリに割り付けられる場合、前記ハッシュ値フィールド中の値に割り当てられるビット長を短くし、一方前記オブジェクト識別子に割り当てられるビット長を長くするステップをさらに含む、請求項８に記載の方法。
【請求項１１】
前記短くし且つ長くするステップが、ランダムに与えられる前記オブジェクト識別子の一部又は全部が予め決めておいたビットパターンに一致する場合に実行される、請求項１０に記載の方法。
【請求項１２】
前記ハッシュ値フィールドは、前記参照命令が実行されたかどうかを示すフラグを含み、
前記参照命令の発行に応じて、該フラグを立てるステップをさらに含む、請求項９に記載の方法。
【請求項１３】
前記フラグの立っているハッシュ値フィールドを含む実行時オブジェクトのハッシュ値の参照命令が実行された場合、前記計算された値に置き換えるステップが実行されない、請求項１２に記載の方法。
【請求項１４】
前記メモリが、該メモリのヒープ領域であり、
該ヒープ領域をスキャンし、使われていない実行時オブジェクトのハッシュ値フィールドの前記値を見つけて、新たな実行時オブジェクトに前記見つけた値を使用するステップをさらに含む、請求項８に記載の方法。
【請求項１５】
前記スキャンが、ガーベジコレクションにおいて実行される、請求項１４に記載の方法。
【請求項１６】
前記値に割り当てられるビット長が、可変長である、請求項８に記載の方法。
【請求項１７】
前記ハッシュ値フィールドが、前記オブジェクトのオブジェクト・ヘッダ内にある、請求項８に記載の方法。
【請求項１８】
ハッシュ値フィールドを有する実行時オブジェクトを実装するためのプログラム中のオブジェクトの割り付け場所を、該実行時オブジェクトから追跡するためのコンピュータ・システムであって、
前記実行時オブジェクトを格納するメモリと、
請求項１に記載のデータ構造から前記値を取得する取得部と、
前記取得した値に対応する前記オブジェクトの割り付け場所を特定する特定部と
を含む、前記コンピュータ・システム。
【請求項１９】
コンピュータ・システムに、請求項２〜１７のいずれか一項に記載の方法の各ステップを実行させることを含む、コンピュータ・プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、プログラム中のオブジェクトの割り付け場所を追跡する方法、並びにそのコンピュータ・システム及びコンピュータ・プログラムに関する。
【背景技術】
【０００２】
多くのプログラムでは、メモリのヒープ領域に多数のオブジェクトが動的に割り付けられる。該プログラム中、すなわちソースコード又はバイトコード等の中間コード中のオブジェクトの割り付け場所は、該プログラム中に複数存在しうる。該プログラム中のオブジェクトの割り付け場所は、例えばＪａｖａ（商標）言語では、オブジェクトを生成するnew演算子を記述する場所である。該プログラム中に記述されるオブジェクトは、プログラムの実行時にメモリのヒープ領域内に割り付けられる。そこで、プログラムのソースコード中又はバイトコード等の中間コード中のオブジェクトの割り付け場所を、ヒープ領域内に割り付けられたオブジェクトから検出することができれば、効率的なデバッグ又は様々なプログラムの最適化が可能である。
【０００３】
例えば、プログラム実行時のある時点において、メモリリークが疑われているとする。ヒープ領域中で生きている全てのオブジェクトから上記割り付け場所を検出することができれば、プログラム中のオブジェクトを多く割り付ける場所の特定ができる。該特定により、プログラマーはメモリリークを回避するための対策をとることができる。ここで、「メモリリーク」とは、使用可能なメモリ容量が徐々に減っていく現象をいう。メモリリークは、例えば、不要になったオブジェクトがメモリに残存し、蓄積されることによって発生する。「生きているオブジェクト」とは、何らかの処理で使用されるために、該処理が実行されるプログラムからポインタによって参照されている状態のオブジェクトをいう。
【０００４】
また、例えば、あるオブジェクトに複数のスレッドが頻繁にロックをかけているような場合、プログラム中のどの場所で該オブジェクトが割り付けられているかを知ることができれば、例えばある特定のスレッドのために、該オブジェクトのロック予約を止めることもできる（非特許文献１を参照）。
【０００５】
また、プログラム上でのオブジェクトの割り付け場所を特定可能にするために、オブジェクト・ヘッダを拡張し、該拡張された領域に１ワード分の割り付け場所番号を埋め込む方法もある（非特許文献２を参照）。しかし、該方法では、ヘッダを拡張しているので、ヒープ領域がより多く消費される。さらに、拡張ヘッダを用いるとヒープ領域の使われ方そのものが変わってしまうために、ヒープ領域の使われ方についてデバッグすることが困難となる。
【０００６】
プログラム上でのオブジェクトの割り付け場所を特定可能にするために、オブジェクトとプログラムにおける前記オブジェクトの割り付け場所とを１対１で対応付ける対応表を、ヒープ領域の外に用意する方法も考えられる。しかし、上記方法では、対応表がオブジェクトの数に比例して増大する。従って、対応表を記憶するためにメモリが多く消費されてしまう。さらに、上記方法では、どこからも参照されなくなった状態である死んだオブジェクトに関する情報を上記対応表から削除する処理が必要である。従って、上記削除する処理が、プログラムの速度オーバーヘッドを大きくするという不都合がある。
【先行技術文献】
【非特許文献】
【０００７】
【非特許文献１】K. Russell and D. Detlefs, Eliminating Synchronization-Related Atomic Operations with Biased Locking and Bulk Rebiasing, In Proceedings of the ACM SIGPLAN 2006 Conference on Object-Oriented Programming, Systems, Languages, and Applications, pp. 263-272, 2006.
【０００８】
【非特許文献２】R. Shaham, E. K. Kolodner, and M. Sagiv, Heap Profiling for Space-Efficient Java, In Proceedings of the ACM SIGPLAN 2001 Conference on Programming Language Design and Implementation, pp. 104-113, 2001.
【発明の概要】
【発明が解決しようとする課題】
【０００９】
小さなサイズのオブジェクトを大量に割り付けるプログラム、例えばＪａｖａ（商標）言語で作成されたプログラムでは、ヒープ領域中の実行時オブジェクトは、プログラム中のオブジェクトの割り付け位置を示す情報を有していない。
プログラム中のオブジェクトの位置を示す情報が、上記ヒープ領域中の実行時オブジェクトに付加される例はある（上記非特許文献２を参照）。しかし、該例では、ヒープ領域内の余分な領域が消費される。従って、オブジェクトのプログラム中の割り付け場所をメモリ内のヒープ領域の実行時オブジェクトからメモリを多く消費することなく効率的に追跡することは、既存の方法では困難である。従って、プログラム中のオブジェクトの割り付け場所を効率的に追跡する方法が求められている。
【課題を解決するための手段】
【００１０】
本発明は、ハッシュ値フィールドを有する実行時オブジェクトを実装するためのプログラム中のオブジェクトの割り付け場所を、該実行時オブジェクトから追跡することを可能にするための該実行時オブジェクトのデータ構造を提供する。該データ構造は、上記実行時オブジェクトのハッシュ値フィールドがハッシュ値として上記割り付け場所に対応した値とオブジェクト識別子とを含む。プログラム中に記述されるオブジェクトの割り付け場所の上記追跡は、該値に対応する上記オブジェクトの割り付け場所を特定することによって行われる。
【００１１】
本発明はまた、ハッシュ値フィールドを有する実行時オブジェクトを実装するためのプログラム中のオブジェクトの割り付け場所を、該実行時オブジェクトから追跡するための方法を提供する。該方法は、コンピュータ・システムに下記ステップを実行させることを含む。該ステップは、
上記データ構造から上記割り付け場所に対応した値を取得するステップと、
上記取得した値に対応する上記オブジェクトの割り付け場所を特定するステップと
を含む。
【００１２】
本発明の１つの実施態様では、上記特定が、ハッシュ値が参照されたことのある実行時オブジェクトのハッシュ値フィールドに含まれる上記割り付け場所に対応した値（以下、第１の値）と該第１の値に対応する割り付け場所との対応付けを記録する対応表（以下、第１の対応表）から、上記第１の値に対応する割り付け場所を特定することによって行われる。
【００１３】
本発明の１つの実施態様では、上記第１の値が、該第１の値を含む上記実行時オブジェクトのハッシュ値が参照されることに応じて求められる値である。
【００１４】
本発明の１つの実施態様では、上記第１の値が、二分木構造によって求められる値である。
【００１５】
本発明の１つの実施態様では、上記二分木構造が上記第１の値と該第１の値に対応する割り付け場所との対応関係を示し、並びに上記二分木構造の枝が上記第１の値のビット表示の各ビットを示し、及び上記二分木構造のノードが上記オブジェクトの割り付け場所を示す。
【００１６】
本発明の１つの実施態様では、上記特定が、ハッシュ値が参照されたことのない実行時オブジェクトのハッシュ値フィールドに含まれる上記割り付け場所に対応した値（以下、第２の値）と該第２の値に対応する割り付け場所との対応付けを記録する対応表（以下、第２の対応表）から、上記第２の値に対応する割り付け場所を特定することによって行われる。
【００１７】
本発明はまた、ハッシュ値フィールドを有する実行時オブジェクトを実装するためのプログラム中のオブジェクトの割り付け場所を、該実行時オブジェクトから追跡することを可能にするための方法を提供する。該方法は、コンピュータ・システムに下記ステップを実行させることを含む。該ステップは、
上記実行時オブジェクトのメモリへの割り付けに応じて、
上記データ構造の上記ハッシュ値フィールド内に、上記プログラム中のオブジェクトの上記割り付け場所に対応した値を埋め込むステップを含み、上記ハッシュ値フィールドがハッシュ値として上記埋め込まれた値とオブジェクト識別子とを含み、上記追跡が該埋め込まれた値に対応する上記オブジェクトの割り付け場所を特定することによって行われる。
【００１８】
本発明の１つの実施態様では、上記方法は、コンピュータ・システムに下記ステップをさらに実行させることを含む。該ステップは、
実行時オブジェクトのハッシュ値の参照命令が実行されることに応じて、
上記埋め込まれた値を、計算された値に置き換えるステップと、
上記計算された値と上記埋め込まれた値との対応表をメモリ内に作成するステップと
を含む。
【００１９】
本発明の１つの実施態様では、上記方法は、コンピュータ・システムに下記ステップをさらに実行させることを含む。該ステップは、
上記プログラム中のオブジェクトの割り付け場所が同一である実行時オブジェクトが多くメモリに割り付けられる場合、上記ハッシュ値フィールド中の値に割り当てられるビット長を短くし、一方上記オブジェクト識別子に割り当てられるビット長を長くするステップを含む。
【００２０】
本発明の１つの実施態様では、上記短くし且つ長くするステップが、ランダムに与えられる上記オブジェクト識別子の一部又は全部が予め決めておいたビットパターンに一致する場合に実行される。
【００２１】
本発明の１つの実施態様では、上記ハッシュ値フィールドは、上記参照命令が実行されたかどうかを示すフラグを含む。また、上記方法は、コンピュータ・システムに下記ステップをさらに実行させることを含む。該ステップは、上記参照命令の発行に応じて、該フラグを立てるステップを含む。
【００２２】
本発明の１つの実施態様では、上記フラグの立っているハッシュ値フィールドを含む実行時オブジェクトのハッシュ値の参照命令が実行された場合、上記計算された値に置き換えるステップが実行されない。
【００２３】
本発明の１つの実施態様では、上記メモリが、該メモリのヒープ領域である。また、上記方法は、コンピュータ・システムに下記ステップをさらに実行させることを含む。該ステップは、該ヒープ領域をスキャンし、使われていない実行時オブジェクトのハッシュ値フィールドの上記値を見つけて、新たな実行時オブジェクトに上記見つけた値を使用するステップを含む。
【００２４】
本発明の１つの実施態様では、上記スキャンが、ガーベジコレクションにおいて実行される。
【００２５】
本発明の１つの実施態様では、上記値に割り当てられるビット長が、可変長である。
【００２６】
本発明の１つの実施態様では、上記ハッシュ値フィールドが、上記オブジェクトのオブジェクト・ヘッダ内にある。
【００２７】
本発明はまた、コンピュータ・システムに上記方法のいずれか１つに記載の各ステップを実行させるコンピュータ・プログラムを提供する。
【００２８】
本発明はまた、ハッシュ値フィールドを有する実行時オブジェクトを実装するためのプログラム中のオブジェクトの割り付け場所を、該実行時オブジェクトから追跡するためのコンピュータ・システムを提供する。該コンピュータ・システムは、
上記実行時オブジェクトを格納するメモリと、
上記データ構造から上記値を取得する取得部と、
上記取得した値に対応する上記オブジェクトの割り付け場所を特定する特定部と
を含む。
【００２９】
本発明はまた、ハッシュ値フィールドを有する実行時オブジェクトを実装するためのプログラム中のオブジェクトの割り付け場所を、該実行時オブジェクトから追跡することを可能にするためのコンピュータ・システムを提供する。該コンピュータ・システムは、
上記実行時オブジェクトのメモリへの割り付けに応じて、
上記データ構造の上記ハッシュ値フィールド内に、上記プログラム中のオブジェクトの上記割り付け場所に対応した値を埋め込む埋込部を含む。ここで、上記ハッシュ値フィールドがハッシュ値として上記埋め込まれた値とオブジェクト識別子とを含み、上記追跡が該埋め込まれた値に対応する上記オブジェクトの割り付け場所を特定することによって行われる。
【００３０】
本発明の１つの実施態様では、上記コンピュータ・システムはさらに、
上記実行時オブジェクトのハッシュ値の参照命令が実行されることに応じて、
上記埋め込まれた値を、計算された値に置き換える置換部と、
上記計算された値と上記埋め込まれた値との対応表をメモリ内に作成する作成部と
を含む。
【００３１】
本発明の１つの実施態様では、上記コンピュータ・システムはさらに、上記プログラム中のオブジェクトの割り付け場所が同一である実行時オブジェクトが多くメモリに割り付けられる場合、上記ハッシュ値フィールド中の値に割り当てられるビット長を短くし、一方上記オブジェクト識別子に割り当てられるビット長を長くする調整部をさらに含む。
【００３２】
本発明の１つの実施態様では、上記コンピュータ・システムはさらに、メモリのヒープ領域をスキャンし、且つ使われていない実行時オブジェクトのハッシュ値フィールドから値を取得する再利用部を含む。
【発明の効果】
【００３３】
本発明の実施態様によれば、オブジェクトを割り付けた場所を探索するための情報が、ヒープ領域上のオブジェクトのハッシュ値フィールドに保持される。よって、上記情報が保持されることによって、ヒープ領域の消費量が増加しない。従って、デバッグ時と実行時とのヒープ領域についての環境が同一に保たれる。
また、本発明の実施態様によれば、ヒープ領域外のメモリ消費量が、オブジェクト数に比例して増加しない。すなわち、オブジェクトの数の増加に対して、メモリ消費量の増加の程度は、緩やかである。従って、メモリ消費量の増大を抑えたオブジェクト割り付け場所の探索が可能である。
【図面の簡単な説明】
【００３４】
【図１】従来技術における実行時オブジェクトのデータ構造の例を示す。
【図２Ａ】本発明の実施態様における、割り付け場所に対応した値を、図１のデータ構造（１０１）に含まれるハッシュ値フィールドに埋め込んだオブジェクトのデータ構造を示す。
【図２Ｂ】本発明の実施態様における、図２Ａに含まれるハッシュ値フィールドの詳細を示す。
【図３】本発明の実施態様における、図２Ｂで示すハッシュ値フィールド中のビットの振り分け方を可変にする概念図を示す。
【図４Ａ】本発明の実施態様における、図２Ａで示すオブジェクトにおいて、値（静的番号）と値（動的番号）とを併用する例を示す。
【図４Ｂ】本発明の実施態様における、図４Ａの併用する例の処理フローチャートを示す。
【図４Ｃ】本発明の実施態様における、プログラム中のオブジェクト割り付けによってハッシュ値フィールドに値が埋め込まれた実行時オブジェクトのデータ構造の例を示す。
【図４Ｄ】本発明の実施態様における、プログラム中のハッシュ値参照命令によってハッシュ値フィールドの値が置き換えられる実行時オブジェクトのデータ構造の例を示す。
【図５】本発明の実施態様における、割り付け値フィールドのビット長を動的に縮めていく様子を示す。
【図６Ａ】本発明の実施態様における、図５に示すハッシュ値フィールドにおいて、２つの割り付け場所ｘ及びｙに二分木を用いて値（動的番号）を割り振る例を示す。
【図６Ｂ】本発明の実施態様における、図５に示すハッシュ値フィールドにおいて、２つの割り付け場所ｘ及びｙに値（動的番号）を割り振るための二分木を示す。
【図７】本発明の実施態様における、指定された割り付け場所に指定されたビット長の新たな動的番号を割り振る処理のフローチャートを示す。
【図８Ａ】本発明の実施態様における、図２Ｂのハッシュ値フィールドのための定数定義を実装するプログラム例を示す。
【図８Ｂ】本発明の実施態様における、図２Ａのデータ構造を実装するためのプログラム例を示す。
【図８Ｃ】本発明の実施態様における、図６Ｂの二分木に関するデータ構造を実装するためのプログラム例を示す。
【図８Ｄ】本発明の実施態様における、ハッシュ値を参照する関数に、ハッシュ値フィールドの値（静的番号）を動的番号へと書き換えるアルゴリズムの組み込みを実装するためのプログラム例を示す。
【図８Ｅ】本発明の実施態様における、ハッシュ値を参照する関数に、ハッシュ値フィールドの値（静的番号）を動的番号へと書き換えるアルゴリズムの組み込みを実装するためのプログラム例を示す。
【図８Ｆ】本発明の実施態様における、ハッシュ値を参照する関数に、ハッシュ値フィールドの値（静的番号）を動的番号へと書き換えるアルゴリズムの組み込みを実装するためのプログラム例を示す。
【図９Ａ】本発明の実施態様における、値（静的番号）を埋め込んだ実行時オブジェクトのデータ構造を作成する方法、及び該データ構造を利用して、プログラム中のオブジェクトの割り付け場所を追跡するための方法のフロー図を示す。
【図９Ｂ】本発明の実施態様における、値（動的番号）を埋め込んだ実行時オブジェクトのデータ構造を作成する方法、及び該データ構造を利用して、プログラム中のオブジェクトの割り付け場所を追跡するための方法のフロー図を示す。
【図９Ｃ】本発明の実施態様における、値（静的番号）及び値（動的番号）をとも使用した実行時オブジェクトのデータ構造を作成する方法、及びそのデータ構造を利用してオブジェクトの割り付け場所を追跡するための方法のフロー図を示す。
【図１０】本発明の実施態様における、図９Ａ〜図９Ｃで示す、オブジェクトの割り付け場所の追跡結果の出力例を示す。
【図１１】本発明の実施態様における、２つのアプリケーション（Trade 6及びSPECjbb2005）における、クラスごとの割り付け場所の静的な数を示す。
【図１２】本発明の実施態様における、図１１で使用した２つのアプリケーション（Trade 6,SPECjbb2005）における、ハッシュ値の平均衝突数と最大衝突数を示す。
【図１３Ａ】本発明の実施態様における、図９Ａ〜図９Ｃで示す、プログラムを追跡する処理を実行するコンピュータ・システムの有する機能を図示する機能ブロック図を示す。
【図１３Ｂ】本発明の実施態様における、図４Ｂ、図７及び図９で示す、ハッシュ値フィールドに保持されている値（静的番号）を値（動的番号）に置き換える処理を実行するコンピュータ・システムの有する機能を図示する機能ブロック図を示す。
【図１３Ｃ】本発明の実施態様における、図９Ａ〜図９Ｃで示す、ハッシュ値フィールドに値（静的番号）を埋め込む処理を実行するコンピュータ・システムの有する機能を図示する機能ブロック図を示す。
【図１３Ｄ】本発明の実施態様における、使われていない実行時オブジェクトのハッシュ値フィールドの値を別の実行時オブジェクトの値とする処理を実行するコンピュータ・システムの有する機能を図示する機能ブロック図を示す。
【図１４】本発明の実施態様における、図１３に示すコンピュータ・ハードウェアのブロック図を示す。
【発明を実施するための形態】
【００３５】
本発明の実施態様において、「オブジェクト」とは、プログラム上の抽象化された手続きの対象を具体化したものである。
本発明の実施態様において、「実行時オブジェクト」は、プログラム中に記述されるオブジェクトの割り付け場所から生成されるオブジェクトである。「実行時オブジェクト」は、上記プログラムの実行時に、メモリ内、例えばヒープ領域内に割り付けられたオブジェクトである。実行時オブジェクトは、例えばクラスから生成される。実行時オブジェクトは、上記プログラムの実行が、例えば中断又は完了した場合であっても、ヒープ領域に存在しうる。実行時オブジェクトは、ハッシュ値フィールドを有する。また、実行時オブジェクトは、オブジェクトに関する情報を保持するためのオブジェクト・ヘッダを有しうる。該オブジェクト・ヘッダは、例えば、クラスポインタ、フラグ及びモニタを含みうる。また、上記ハッシュ値フィールドは、オブジェクト・ヘッダに含まれていてもよい。
なお、本発明の実施態様における「ヒープ領域」は、プログラムに使用されるヒープ領域全体ではなく、上記ヒープ領域全体の一部であって、実行時オブジェクトが割り付けられるヒープ領域のことをいう。上記ヒープ領域は、例えば、ガーベジコレクションの対象となるヒープ領域である。
【００３６】
本発明の実施態様において、「ハッシュ値フィールド」とは、上記実行時オブジェクトが有するフィールドである。ハッシュ値フィールドには、実行時オブジェクトのハッシュ値が保持される。ハッシュ値とは、実行時オブジェクトの同一性を識別するための識別子である。但し、異なる２つの実行時オブジェクトにおいて、同一のハッシュ値が保持されることは、既存のハッシュ値の仕様で許容されている。
ハッシュ値フィールドは、割り付け値フィールド及び識別子フィールドを含む。ハッシュ値フィールドは、参照フラグを含んでもよい。ハッシュ値フィールドについては、後述の図２Ｂの説明で詳しく述べる。
【００３７】
本発明の実施態様において、「割り付け場所に対応した値」とは、プログラム上のオブジェクト割り付け場所を一意に識別する値である。割り付け場所に対応した値は、上記割り付け値フィールドに保持される。上記値には、値（静的番号）及び値（動的番号）がある。
上記値（静的番号）は、例えば、プログラムの行番号及びプログラム・コードにおける相対的な位置を表す値である。上記値（静的番号）は、上記行番号又は上記相対的な位置を表す値に対応付けられた識別子であってもよい。コンピュータ・システムは、例えば、該識別子と行番号との対応が保存される対応表を参照することで、識別子から行番号を求めることができる。
上記値（動的番号）は、上記値（静的番号）に対応付けられた値である。コンピュータ・システムは、上記値（動的番号）と上記値（静的番号）との対応付けが保存される対応表を参照することで、上記値（動的番号）から上記値（動的番号）を求めることができる。
【００３８】
本発明の実施態様において、「オブジェクト識別子」とは、ランダムな値である。「オブジェクト識別子」は、上記識別子フィールドに保持される。
上記割り付け場所に対応した値とオブジェクト識別子とを組み合わせた値が、上記ハッシュ値になる。上記組み合わせには、上記参照フラグが含まれてもよい。
【００３９】
本発明の実施態様において、「ハッシュ値フィールドを有する実行時オブジェクトを実装するためのプログラム」とは、プログラムの実行環境において、ハッシュ値フィールドを有する実行時オブジェクトをメモリに割り付ける命令を有するプログラムをいう。「ハッシュ値フィールドを有する実行時オブジェクトを実装するためのプログラム」は、例えばソースコード又はバイトコード等の中間コードを含む。また、「ハッシュ値フィールドを有する実行時オブジェクトを実装するためのプログラム」は、例えば、オブジェクト指向型言語で記述されたプログラム又は上記プログラムがコンパイルされた中間コードである。オブジェクト指向型言語は、例えばＪａｖａ（商標）、Ｃ＋＋であるがこれらに限定されない。プログラムの実行環境は、例えば、ＪａｖａＶＭ（商標）（Ｊａｖａ  Ｖｉｒｔｕａｌ  Ｍａｃｈｉｎｅ）であるが、これに限定されない。
【００４０】
本発明の実施態様において、「オブジェクトの割り付け場所」とは、ハッシュ値フィールドを有する実行時オブジェクトを実装するためのプログラム中において、例えば生成命令又はコピー命令により、オブジェクトがオブジェクト変数に割り付けられる、プログラム中の場所をいう。プログラム中の場所は、例えば、プログラムの行番号又はプログラム・コードにおける相対的な位置である。
【００４１】
本発明の実施態様において、「追跡する」とは、実行時オブジェクトから、該実行時オブジェクトを実装するためのプログラム中のオブジェクトの割り付け場所を特定することをいう。
【００４２】
本発明の実施態様において、「第１の対応表」とは、ハッシュ値が参照されたことのある実行時オブジェクトのハッシュ値フィールドに含まれる、割り付け場所に対応した値（以下、第１の値）と該第１の値に対応する割り付け場所を特定するための情報との対応付けを記録する。「第１の値に対応する割り付け場所を特定するための情報」とは、上記値（静的番号）を特定するための情報である。
【００４３】
本発明の実施態様において、「第２の対応表」とは、ハッシュ値が参照されたことのない実行時オブジェクトのハッシュ値フィールドに含まれる、割り付け場所に対応した値（以下、第２の値）と該第２の値に対応する割り付け場所との対応付けを記録する。
【００４４】
以下、図面に従って、本発明の実施態様を説明する。本実施態様は、本発明の好適な態様を説明するためのものであり、本発明の範囲をここで示すものに限定する意図はないことを理解されたい。また、以下の図を通して、特に断らない限り、同一の符号は、同一の対象を指す。
【００４５】
以下では、最初に、図１において従来技術における実行時オブジェクトのデータ構造の例を説明する。次に、図２Ａ及びＢにおいて本発明の実施態様における実行時オブジェクトのデータ構造の例を説明する。
【００４６】
図１は、従来技術における実行時オブジェクトのデータ構造の例を示す。
図１は、Ｊａｖａ（商標）言語で作成されたプログラムによって割り付けられた実行時オブジェクトの例である。
実行時オブジェクト（１０１）は、メモリ内のヒープ領域内に実装される。実行時オブジェクトは（１０１）、オブジェクト・ヘッダと、インスタンス変数を保持するオブジェクト・フィールドとを備える。
オブジェクト・ヘッダは、例えば、３ワード構成である。なお、１ワードは３２ビットである。１ワード目には、クラスポインタが保持される。２ワード目には、ハッシュ値及びフラグが保持される。３ワード目には、モニタが保持される。
クラスポインタは、オブジェクトが属しているクラスを指すポインタである。ハッシュ値は、上記クラスに属するオブジェクトの同一性を識別するために付けられる値である。フラグは、例えばオブジェクトの各種状態を示す。該状態は、例えばロック状態である。モニタは、ガーベジコレクションのために使用される。
オブジェクト・ヘッダは、２ワード又は１ワードで構成される場合もある。
オブジェクトのフィールドは、オブジェクトの本体であるインスタンス変数が格納されるフィールドである。
実行時オブジェクト（１０２）は、実行時オブジェクト（１０１）が従来技術によって拡張された例を示す。従来技術では、実行時オブジェクト（１０１）に割り付け場所を特定するための情報を付加する場合、上記オブジェクト・ヘッダを拡張する。そして、該拡張された領域に１ワード分の割り付け場所番号が埋め込まれる。従って、実行時オブジェクト（１０１）は、実行時オブジェクト（１０２）のようなデータ構造になる。実行時オブジェクト（１０２）は、ヘッダが拡張されているため、実行時オブジェクト（１０１）に比べ、ヒープ領域がより多く消費される。
【００４７】
図２Ａは、本発明の実施態様における、割り付け場所に対応した値を、図１のデータ構造（１０１）に含まれるハッシュ値に埋め込んだオブジェクトのデータ構造を示す。
実行時オブジェクト（２０１）では、ハッシュ値が格納されるハッシュ値フィールドの一部に、割り付け場所に対応した値が埋め込まれる。実行時オブジェクト（図１、１０２）のような拡張はされない。従って、ヒープ領域の消費量は、割り付け場所に対応した値が埋め込まれる前後で変化しない。また、上記ハッシュ値フィールドの残りの部分は、オブジェクト識別子と名付けられる。
【００４８】
図２Ｂは、本発明の実施態様における、図２Ａに含まれるハッシュ値フィールドの詳細を示す。
ハッシュ値フィールド（２０２）は、割り付け値フィールド及び識別子フィールドで構成される。ハッシュ値フィールド（２０２）は、ハッシュ値フィールド（２０３）のように、さらに参照フラグで構成されていてもよい。
割り付け値フィールドには、割り付け場所に対応した値が保持される。該値は、値（静的番号）又は値（動的番号）である。
識別子フィールドにはオブジェクト識別子が保持される。オブジェクト識別子はランダムな値である。
参照フラグは、ハッシュ値フィールドがプログラムによって参照されたか否かを表すフラグである。参照フラグは、例えば１ビットの値であり、ハッシュ値フィールドが参照される前は０、参照された後は１が設定される。
【００４９】
ハッシュ値フィールド（２０２）は、少なくとも２ビット長で表される。該ビットは、上記割り付け値フィールド及び識別子フィールドに、例えば、上位ビットから順に割り当てられる。ハッシュ値フィールド（２０２）が、例えば８ビットで表されるとする。割り付け値フィールドに５ビット、識別子フィールドに３ビット割り当てられるとするならば、割り付け値フィールドには、２＾５＝３２通りの割り付け場所に対応した値が格納できる。識別子フィールドには、２＾３＝８通りのオブジェクト識別子が格納できる。また、ハッシュ値フィールド（２０２）に格納されたハッシュ値が（０１０１０００１）２ならば、割り付け場所に対応した値は（０１０１０）２であり、オブジェクト識別子は（００１）２である。
また、ハッシュ値フィールド（２０３）のように、ハッシュ値フィールドが、参照フラグを構成に含むならば、ハッシュ値フィールドは少なくとも３ビット長で表される。参照フラグは、参照の有無を表せるだけのビット長があればよく、例えば、１を参照されたとし、０を参照されていないとするならば、１ビットが割り当てられる。ハッシュ値フィールド（２０３）が、例えば１６ビットで表されるとする。割り付け値フィールドに１０ビット、識別子フィールドに５ビット、参照フラグに１ビット割り当てられるとするならば、割り付け値フィールド（２０３）には、２＾１０＝１０２４通りの割り付け場所に対応した値が格納できる。識別子フィールドには、２＾５＝３２通りのオブジェクト識別子が格納できる。また、ハッシュ値フィールド（２０３）に格納されたハッシュ値が（１０１１１０１１１０１１１０１１）２ならば、割り付け場所に対応した値は（１０１１１０１１１０）２、オブジェクト識別子は（１１１０１）２、参照フラグは１である。
【００５０】
上記割り付け場所に対応した値には、１ワードより短いビット長しか割り当てられていない。上記ビット長は、プログラム中の割り付け場所を指定するには不十分な長さに思えるかもしれない。しかし、実行時オブジェクト中には、該オブジェクトのクラスを一意に識別できるクラスポインタがある。よって、割り付け場所に対応した値は、プログラム全体で一意である必要はない。割り付け場所に対応した値は、同一のクラスのオブジェクトの割り付け場所を一意に識別できればよい。従って、ほとんどの場合、上記割り付け場所に対応した値を表すビットのビット長は、１ワードよりも短いビット長で十分である。
なお、上記ビット長が不足する場合の対応は、下記図３の説明において述べる。
【００５１】
ここで、ハッシュ値フィールドに格納されているハッシュ値は、オブジェクト同士を識別するために使用される値である。例えば、Ｊａｖａ（商標）言語で作られたプログラムでは、オブジェクトが割り付けられるタイミングで、ハッシュ値にランダムな値が設定される。本発明の実施態様では、上記ハッシュ値に、割り付け場所に対応した値、オブジェクト識別子及び参照フラグが埋め込まれうる。そして、上記埋め込みが行われたハッシュ値は、依然として、オブジェクト同士を識別するために使用される。
【００５２】
図３は、本発明の実施態様における、図２Ｂで示すハッシュ値フィールド中のビットの振り分け方を可変にする概念図を示す。
本発明の実施態様では、同じ場所で割り付けられた実行時オブジェクトの割り付け場所に対応する値（静的番号）は同じである。従って、値（静的番号）のみを用いた場合、ハッシュ値を表すビットに含まれる上記値（静的番号）を表すビットが、同じ場所で割り付けられた実行時オブジェクト同士で同じ値となる。
ここで、上記ハッシュ値フィールド中のビットの振り分け方が固定の場合、割り付け場所に対応する値に割り当てられたビット長の分だけ、オブジェクト識別子に割り当てうるビット長は短くなる。つまり、オブジェクト識別子によって識別されるオブジェクトの数は、上記割り当てうるビット長が短いほど少なくなる。従って、プログラム・コード上の同じ場所で大量の実行時オブジェクトが割り付けられると、ハッシュ値の衝突が生じやすくなる。
【００５３】
ハッシュ値の衝突とは、異なるオブジェクトが同一ハッシュ値を有することをいう。異なるクラスのオブジェクト同士は、ハッシュ値が同じだとしても、ハッシュ値を比較されることは普通のプログラムでは稀である。しかし、同一クラスのオブジェクト同士は、異なるクラスのオブジェクト同士に比べてハッシュ値を比較されることが多い。従って、上記ハッシュ値は、少なくとも同一クラスのオブジェクトについては、異なった値をとることが望ましい。
【００５４】
上記ハッシュ値の衝突を避けるために、本発明の実施態様では、ソースコードの構造から予想される同じ場所で割り付けられるオブジェクトの量に応じて、割り付け値フィールドのビット長を可変にする。以下では、図３に示すシナリオ（３０１）及びシナリオ（３０２）を例として上記可変にする方法を説明する。
【００５５】
シナリオ（３０１）は、同一場所でオブジェクトが大量に割り付けられている例を示す。シナリオ（３０１）で示すコードでは、ループによって同一オブジェクトが大量に割り付けられる。シナリオ（３０１）で示すようなコードがプログラム中にある場合、該コードによって割り付けられるオブジェクトの有する識別子フィールドのビット長を長くし、割り付け値フィールドのビット長を短くすることが有効である。通常のプログラムでは、あるクラスのオブジェクトを大量に割り付ける場所はクラス毎に少数であると考えられる。従って、割り付け値フィールドのビット長は短くても構わない。
【００５６】
シナリオ（３０２）は、同一場所でオブジェクトが大量に割り付けられにくい例を示す。シナリオ（３０２）で示すコードでは、エラーの種類に応じて異なるオブジェクトが割り付けられる。シナリオ（３０２）に示すコードでは、発生したエラーに応じて、オブジェクトが１つ割り付けられるのみであり、各オブジェクトが同じ場所で大量に割り付けられることは少ない。また、発生していないエラーに対応するオブジェクトは割り付けられない。
通常のプログラムでは、シナリオ（３０２）で示すコードのように、オブジェクトをほとんど割り付けない場所は多数あると考えられる。シナリオ（３０１）で示すようなコードがプログラム中にある場合、割り付け値フィールドのビット長を長くし、識別子フィールドのビット長を短くすることが有効である。割り付けられるオブジェクトはほとんど無いため、識別子フィールドのビット長は短くても構わない。
【００５７】
ある割り付け場所で、どれだけの数のオブジェクトが割り付けられるかは、一般にはプログラムが実行されるまでわからない。そこで、本発明の実施態様では、割り付け値フィールドのビット長を、同一の割り付け場所でオブジェクトが多く割り付けられることに応じて動的に縮小させる。上記縮小させるために、各割り付け場所に複数の値（動的番号）が割り振られる。割り付け場所に最初に割り振られる値（動的番号）は、長いビット長を持つ。該値は、値（静的番号）であってもよい。上記割り付け場所で多数のオブジェクトが割り付けられると、よりビット長が短い新たな値（動的番号）が割り付け場所に割り振られる。上記ビット長が短い新たな値（動的番号）が割り振られると、上記オブジェクトの割り付け値フィールドのビット長は、新たな値（動的番号）のビット長に縮小され、上記短い新たな値（動的番号）が埋め込まれる。上記割り付け場所でさらに多数のオブジェクトが割り付けられると、さらに短い新たな値（動的番号）が割り付け場所に割り振られる。上記複数の値（動的番号）と割り付け場所との対応表は、ヒープ領域以外の記憶域に持つ。
【００５８】
上記割り付け値フィールドのビット長を動的に縮める方法では、対応表を参照するという専用の処理が、オブジェクト割り付け時に必要になる。従って、単にオブジェクトを割り付ける場合に比べ、プログラムの速度オーバーヘッドが大きくなる。しかし、実際のプログラムでは、ほとんどのオブジェクトのハッシュ値は、実行中に一度も参照されることはない。また、例えばＪａｖａ（商標）言語では、ハッシュ値を参照するメソッドであるhashCode()メソッドを含むオブジェクトのクラスの多くは、hashCode()メソッドをオーバーライドしている。そして、該オーバーライドしたメソッドにおいて、ハッシュ値は独自に定義される。従って、上記ハッシュ値フィールドに埋め込まれているハッシュ値が参照されることはない。
【００５９】
値（動的番号）を用いる場合、上記専用の処理が必要になる。一方、値（静的番号）を用いる場合、上記専用の処理は必要ではない。よって、値（静的番号）を用いる場合、値（動的番号）を用いる場合に比べ、プログラムは速く動作する。しかし、上記値（静的番号）を用いる場合、同じ場所で割り付けられるオブジェクトの数に応じて、割り付け値フィールドのビット長を変更させることはできない。
そこで、以下では、値（静的番号）と値（動的番号）とを併用する方法を述べる。
【００６０】
図４Ａは、本発明の実施態様における、図２Ａで示すオブジェクトにおいて、値（静的番号）と値（動的番号）とを併用する例を示す。
実行時オブジェクト（４０１）は、値（静的番号）をプログラム中のオブジェクトの割り付け場所に対応した値として用いた場合の実行時オブジェクトを示す。実行時オブジェクト（４０２）は、値（動的番号）をプログラム中のオブジェクトの割り付け場所に対応した値として用いた場合の実行時オブジェクトを示す。
値（静的番号）と値（動的番号）とを併用する場合、コンピュータ・システムは、実行時オブジェクトがヒープ領域に割り付けられることに応じて、値（静的番号）を実行時オブジェクト（４０１）のハッシュ値フィールドに埋め込む。また、コンピュータ・システムは、実行時オブジェクトのハッシュ値を参照する命令が初めて実行されるタイミングで、値（静的番号）を値（動的番号）に置き換える。
【００６１】
以下に、値（静的番号）のハッシュ値フィールドへの埋め込みを詳しく説明する。
実行時オブジェクトがヒープ領域に割り付けられることに応じて、コンピュータ・システムは、値（静的番号）を上記実行時オブジェクトのハッシュ値フィールドに埋め込む。コンピュータ・システムは、値（静的番号）が固定長ならば高速にハッシュ値フィールドに、値（静的番号）埋め込むことができる。ここで、コンピュータ・システムは、上記値（静的番号）に対応する識別子をハッシュ値フィールドに埋め込んでもよい。併せてコンピュータ・システムは、ハッシュ値が一度も参照されていないことを示す参照フラグをハッシュ値フィールドに埋め込む。参照フラグには、例えば、上記オブジェクトが参照されていない場合を０とするならば、コンピュータ・システムは、「０」を設定する。なお、コンピュータ・システムは、オブジェクト識別子を設定する必要はない。
【００６２】
以下に、値（静的番号）の値（動的番号）への置き換えを詳しく説明する。
実行時オブジェクトのハッシュ値を参照する命令が初めて実行されることに応じて、コンピュータ・システムは、ハッシュ値フィールドを置き換える。該書き換えでは、値（動的番号）がハッシュ値フィールドに埋め込まれる。また、コンピュータ・システムは、乱数を生成し、そして該生成した乱数をオブジェクト識別子として、ハッシュ値フィールドに埋め込む。さらにコンピュータ・システムは、上記参照フラグにオブジェクトが参照されたことを示す値を設定する。該値は、例えば「１」である。コンピュータ・システムは、上記置き換えられたハッシュ値フィールドの値を、ハッシュ値として参照元に返す。なお、一度置き換えられたハッシュ値フィールドは、該ハッシュ値フィールドを有するオブジェクトの生存期間中にさらに置き換えられることはない。
【００６３】
上記「実行時オブジェクトがヒープ領域に割り付けられること」及び「実行時オブジェクトのハッシュ値を参照する命令が初めて実行されること」は、例えば、プログラムが、just-in-time（ＪＩＴ）コンパイルされる時に、コンピュータ・システムによって検出されてもよい。また、プログラムがインタプリタによって実行される場合、上記「実行時オブジェクトがヒープ領域に割り付けられること」及び「実行時オブジェクトのハッシュ値を参照する命令が初めて実行されること」は、プログラムがメモリ上にロードされること又は実行されることに応じて、コンピュータ・システムによって検出されてもよい。
上記検出は、ソースコード又は中間コードに含まれる割り付ける命令及び参照する命令がスキャンされることで行われうる。
【００６４】
また、上記ハッシュ値フィールドの置き換えを行う処理が、クラスライブラリに含まれる割り付ける命令及び参照する命令自身に追加されてもよい。
【００６５】
なお、値（静的番号）と値（動的番号）とを併用する場合、オブジェクトのハッシュ値が参照されたか否かを示す参照フラグに１ビットが必要になる。従って、割り付け値フィールド又は識別子フィールドに用いることのできるビットのビット長が１ビット短くなる。
【００６６】
値（静的番号）と値（動的番号）とを併用することにより、値（動的番号）のみを使用する場合に比べて、速度オーバーヘッドが減らされうる。また、値（静的番号）に値（動的番号）よりも長いビット長を用いることで、値（動的番号）のみを使用する場合に比べて、割り付け場所に対応する値を保持するビット長が不足する可能性が減らされうる。
【００６７】
図４Ｂは、本発明の実施態様における、図４Ａの併用する例の処理フローチャートを示す。
ステップ４１０は、処理の開始である。
ステップ４１０では、コンピュータ・システムは、プログラム中のオブジェクトの割り付け場所を追跡されるプログラム（以下、「追跡されるプログラム」という場合がある）を実行する。該実行により、追跡されるプログラムに含まれる少なくとも１の命令が実行される。
ステップ４１１では、コンピュータ・システムは、実行される命令が全て終了したかどうかを判定する。コンピュータ・システムは、上記命令が全て終了するまで、ステップ４１２〜４２０を繰り返す。命令が全て終了していない場合、コンピュータ・システムは、次に実行される命令を上記プログラムから取得し、該処理はステップ４１２に進む。命令が全て終了している場合、ステップ４２２に進み、該処理は終了する。
ステップ４１２では、コンピュータ・システムは、上記取得した命令が、オブジェクトを割り付ける命令かどうかを判定する。取得した命令がオブジェクトを割り付ける命令の場合、該処理は、ステップ４１３に進む。取得した命令がオブジェクトを割り付ける命令ではない場合、該処理は、ステップ４１４に進む。
ステップ４１３では、コンピュータ・システムは、オブジェクトを割り付ける命令を実行し、実行時オブジェクトを生成する。実行時オブジェクトは、メモリ内、特にメモリのヒープ領域内に生成される。コンピュータ・システムは、上記実行時オブジェクトのハッシュ値フィールドに、プログラム中の割り付け場所に対応した値（静的番号）及び参照フラグを埋め込む。コンピュータ・システムは、例えば、第２の対応表から上記値（静的番号）に対応する識別子を取得し、該対応する識別子を上記値（静的番号）として、ハッシュ値フィールドに埋め込んでもよい。コンピュータ・システムが、上記第２の対応表を使用する場合、ユーザは、あらかじめ上記第２の対応表に上記値（静的番号）と上記対応する識別子との対応を保存しておく。また、コンピュータ・システムは、上記参照フラグを設定する場合、実行時オブジェクトが参照されていないことを表す値、例えば０を設定する。上記埋め込みが終了することに応じて、該処理は、ステップ４２１に進む。
ステップ４１４では、コンピュータ・システムは、上記取得した命令が、オブジェクトのハッシュ値を参照する、参照元からの命令かどうかを判定する。上記取得した命令がオブジェクトのハッシュ値を参照する命令の場合、該処理は、ステップ４１５に進む。上記取得した命令がオブジェクトのハッシュ値を参照する命令ではない場合、該処理は、ステップ４２１に進む。
ステップ４１５では、コンピュータ・システムは、参照されるオブジェクトの参照フラグが立っているかどうかを判定する。コンピュータ・システムは、まずハッシュ値が参照される実行時オブジェクトの参照フラグを該実行時オブジェクトのハッシュ値フィールドから取得する。該取得した参照フラグに上記実行時オブジェクトが参照されていないことを表す値が設定されている場合、コンピュータ・システムは、ハッシュ値フィールドに値（静的番号）が埋め込まれていると判断し、処理はステップ４１６に進む。上記取得した参照フラグに上記実行時オブジェクトが参照されていることを表す値が設定されている場合、コンピュータ・システムは、ハッシュ値フィールドに値（動的番号）が埋め込まれていると判断し、処理はステップ４２０に進む。
ステップ４１６では、コンピュータ・システムは値（動的番号）を求める。コンピュータ・システムは、上記値（動的番号）を、例えば後述する二分木によって求める。また、コンピュータ・システムは、上記二分木より、実行時オブジェクトのハッシュ値フィールド中の割り付け場所に対応した値（静的番号）に対応する所定のビット長を有する現在の値（動的番号）を得る。
ステップ４１７では、コンピュータ・システムは、オブジェクト識別子を求める。コンピュータ・システムは、例えばＣ＋＋言語であれば、thisポインタのアドレスのビットの一部をオブジェクト識別子とする。コンピュータ・システムは、例えばＪａｖａ（商標）言語であれば、random関数を用いて取得されるランダムな値をオブジェクト識別子とする。
ステップ４１８では、コンピュータ・システムは、実行時オブジェクトのハッシュ値フィールドに上記値（動的番号）及び上記オブジェクト識別子を書き込む。上記書き込みにおいて、コンピュータ・システムは、オブジェクト割り付け時に実行時オブジェクトのハッシュ値フィールドに書き込まれた値（静的番号）を該ハッシュ値フィールドから取得する。コンピュータ・システムは、上記取得した値（静的番号）と上記求めた値（動的番号）との対応を第１の対応表に保存する。該保存が終了することにともない、コンピュータ・システムは、上記求めた値（動的番号）及び上記オブジェクト識別子を実行時オブジェクトのハッシュ値フィールドに書き込む。
ステップ４１９では、コンピュータ・システムはハッシュ値が参照されたことを示す参照フラグを実行時オブジェクトのハッシュ値フィールドに書き込む。該書き込まれる参照フラグの値は、ステップ４１３で設定された値が０ならば、例えば１である。
ステップ４２０では、コンピュータ・システムは、上記ハッシュ値フィールドの値を該オブジェクトのハッシュ値として参照元に返す。
ステップ４２１では、該処理はステップ４１１に戻る。
ステップ４２２は、該処理の終了である。
【００６８】
図４Ｃは、本発明の実施態様における、プログラム中のオブジェクト割り付けによってハッシュ値フィールドに値が埋め込まれた実行時オブジェクトのデータ構造の例を示す。
プログラム・コード（４３０）では、プログラム中の２つの割り付け場所（００００１）及び（０００１０）において、それぞれ３つのオブジェクトを割り付ける記述がなされている。上記割り付けに対応して、６つの実行時オブジェクト（４３１〜４３６）がメモリ中のヒープ領域に割り付けられる。割り付け場所（００００１）で割り付けられるオブジェクト（４３１〜４３３）のデータ構造は、図４Ａのオブジェクト４０１で示した構造と同じである。すなわち、割り付け場所（００００１）に対応する値（００００１）及び参照フラグがハッシュ値フィールドに埋め込まれている。値（００００１）は、値（静的番号）である。参照フラグは、０である。ここで、０は、ハッシュ値が参照されていないことを表す。また、割り付け場所（０００１０）でのオブジェクト（４３４〜４３６）のデータ構造は、図４Ａの４０１で示したデータ構造と同じである。すなわち、割り付け場所（０００１０）に対応する値（０００１０）及び参照フラグがハッシュ値フィールドに埋め込まれている。値（０００１０）は、値（静的番号）である。参照フラグは、０である。
【００６９】
図４Ｄは、本発明の実施態様における、プログラム中のハッシュ値参照命令によってハッシュ値フィールドの値が置き換えられる実行時オブジェクトのデータ構造の例を示す。
プログラム・コード（４４０）では、プログラム内にオブジェクトのハッシュ値を参照する３つの命令が記述されている。該命令が実行された後の実行時オブジェクトの構造はオブジェクト（４４１〜４４６）に示される。実行時オブジェクト（４４１〜４４６）それぞれは、図４Ｃの実行時オブジェクト（４３１〜４３６）に対応する。
割り付け場所００００１でのオブジェクトobj1[0]及びobj1[1]のハッシュ値参照によって変化した後の実行時オブジェクトobj1[0]及びobj1[1]のデータ構造が４４１及び４４２に示される。実行時オブジェクト（４４１）のハッシュ値フィールドには、割り付け場所に対応する値（動的番号）０００、オブジェクト識別子１０及び参照フラグ１が埋め込まれている。ここで、参照フラグ１は、ハッシュ値が参照されていることを表す。実行時オブジェクト（４４２）のハッシュ値フィールドには、割り付け場所に対応する値（動的番号）０００、オブジェクト識別子０１及び参照フラグ１が埋め込まれている。
同様に、割り付け場所０００１０でのオブジェクトobj2[0]のハッシュ値参照によって変化した後の実行時オブジェクトobj2[0] のデータ構造が４４４に示されている。実行時オブジェクト（４４４）のハッシュ値フィールドには、割り付け場所に対応する値（動的番号）００１、オブジェクト識別子１１及び参照フラグ１が埋め込まれている。他の実行時オブジェクトは、参照されていないので、参照前の図４Ｃのデータ構造のままであり何ら変更されていない。
ここで、プログラム・コード（４４０）が再度実行された場合、実行時オブジェクトobj1[0]のデータ構造（４４１）、実行時オブジェクトobj1[1]のデータ構造（４４２）及び実行時オブジェクトobj2[0]のデータ構造（４４４）は変更されない。すなわち、一度動的番号が割り振られた実行時オブジェクトは、該実行時オブジェクトが生きている間、ハッシュ値フィールドの値が置き換えられることはない。
【００７０】
図５は、本発明の実施態様における、割り付け値フィールドのビット長を動的に縮めていく態様を示す。
最初の値（動的番号）０は、該値（動的番号）の割り付け場所ｘで割り付けたいずれかのオブジェクトのハッシュ値が初めて参照されるごとに、ハッシュ値フィールドに割り振られる。
割り付け場所ｘに最初に割り振られる値（動的番号）０は、相対的に長いビット長を有し、オブジェクト識別子のビット長はＬ０である。該値（動的番号）の割り付け場所で多数のオブジェクトを割り付けられて、さらに上記割り付けられたオブジェクトのハッシュ値が参照されると、後述するタイミングで、よりビット長が短い新たな値（動的番号）が割り付け場所に対応した値（動的番号）として割り振られる。
本発明の実施態様では、新しい値（動的番号）を割り振るタイミングに、確率的なタイミングが用いられる。具体的には、上記参照時にオブジェクト識別子のビット又は該ビットの一部が全てゼロならば、新たなビット長の値（動的番号）１が割り付け場所に対応した値（動的番号）として割り振られる。以下同様に、よりビット長の短い値（動的番号）２，３、・・・ｎがＰ１（＝１／２＾Ｌ１）、Ｐ２（＝１／２＾Ｌ２）・・・Ｐｎ−１（１／２＾Ｌｎ―１）の確率で割り振られていく。
また、図５の右側に示すように、新たに値（動的番号）１，２・・・ｎを割り振るたびに値（動的番号）１，２・・・ｎから割り付け場所ｘへの対応エントリが対応表に追加される。上記対応表は、ヒープ領域の外に割り付けられ、対応表の大きさは値（動的番号）の数に比例する。従って、対応表の大きさは、オブジェクトの数に比例することはない。値（動的番号）の数は、最大でもハッシュ値フィールドのビット長で表せる数である。該数は、ハッシュ値フィールドのビット長が１４の場合、２＾１４を超えることはない。
【００７１】
なお、割り付け値フィールドのビット長を動的に縮めていく方法として、割り付け場所ごとに割り付け回数のカウンタを用意し、割り付け回数が閾値を越えたら新たな値（動的番号）を割り振るという方法がまたありうる。但し、上記カウンタを持つことは、プログラムの処理速度上好ましくない。
【００７２】
図６Ａ及び図６Ｂは、本発明の実施態様における、図５に示すハッシュ値フィールドにおいて、２つの割り付け場所ｘ及びｙに二分木を用いて値（動的番号）を割り振る例を示す。
図６Ａは、（ａ）〜（ｇ）で示される段階ごとに、より短いビット長の値が割り振られる態様を示す。また、図６Ａは、割り付け値フィールドのビット長を動的に縮めていく態様を示す。図６Ｂは、上記（ａ）〜（ｇ）の各段階に対応した二分木上での割り振り動作を示す。ここでは、割り付け場所ｘには、（ａ）、（ｃ）、（ｄ）及び（ｇ）の順番で値（動的番号）00000、0001、001及び10が割り振られる。また、割り付け場所ｙには、（ｂ）、（ｅ）及び（ｆ）の順番で値（動的番号）00001、0100、及び010が割り振られる。説明の便宜のため、値（動的番号）に用いるビット長の最大を５とする。該値（動的番号）の割り振りは、具体的には、図６Ｂに示すような二分木構造で実現する。ここで、二分木構造とは、ノード（節点）が２つのブランチ（枝）を持つ木構造をいう。該木構造は、例えば右側のノードは同じ高さの左側のノードより必ず大きい（小さい）値を持つ。
二分木は、値（動的番号）の符号（エンコーディング）と割り付け場所ｘ又はｙの対応を表す。
以下に、（ａ）〜（ｇ）で示される段階ごとに説明する。
【００７３】
（ａ）割り付け場所ｘに割り付けられたいずれかのオブジェクトのハッシュ値が、最初に参照されることに応じて、値（動的番号）00000がxに割り振られる（図６Ａ（ａ）を見よ）。該割り振りに応じて、図６Ｂ（ａ）に示すように、値（動的番号）00000を枝にもつ対応するクラスの二分木が作成される。ここで、(x)というラベルが付いているノードは、現時点で割り付け場所ｘに割り振ることができるノードを説明のために示しており、上記(x)というラベルが付いているノードに(x)が実際に書き込まれるわけではない。
【００７４】
（ｂ）ｙで割り付けられたいずれかのオブジェクトのハッシュ値が最初に参照されることに応じて、空いている次の５ビット長の値（動的番号）を二分木（図６Ｂ（ｂ）を見よ）から探索して00001が割り振られる（図６Ａ（ｂ）を見よ）。その結果、0、00、000及び0000を表すノードはどの割り付け場所にも割り振れなくなる。なぜならば、ｘとｙの区別がつかなくなるからである。なお、二分木（図６Ｂ（ｂ）を見よ）の(--)というラベルは、現時点でどの割り付け場所にも割り振ることができない値（動的番号）を説明のために示しており、上記(--)というラベルが付いているノードに(--)が実際に書き込まれるわけではない。
【００７５】
（ｃ）ｘで多くのオブジェクトが割り付けられ、且つ該割り付けられたオブジェクトの少なくとも１つのハッシュ値が参照されているうちに、確率Ｐ０でｘの値（動的番号）のビット長が４に縮められる。ｘのために空いている４ビット長の値（動的番号）が二分木（図６Ｂ（ｃ）を見よ）から探索されて、ｘの値（動的番号）0001が割り振られる（図６Ａ（ｃ）を見よ）。
【００７６】
（ｄ）次に、ｘで多くのオブジェクトが割り付けられ、且つ該割り付けられたオブジェクトの少なくとも１つのハッシュ値が参照されているうちに、確率Ｐ１でｘの値（動的番号）のビット長が３に縮められる。ｘのために空いている３ビット長の値（動的番号）が二分木（図６Ｂ（ｄ）を見よ）から探索されて、ｘの値（動的番号）001が求められる（図６Ａ（ｄ）を見よ）。
【００７７】
（ｅ）yで多くのオブジェクトが割り付けられ、且つ該割り付けられたオブジェクトのハッシュ値が参照されているうちに、確率Ｐ０でｙの値（動的番号）のビット長が４に縮められる。ｙのために空いている４ビット長の値（動的番号）が二分木（図６Ｂ（ｅ）を見よ）から探索されて、ｙの値（動的番号）0100が求められる（図６Ａ（ｅ）を見よ）。
【００７８】
（ｆ）次に、yで多くのオブジェクトを割り付け、且つ該割り付けられたオブジェクトのハッシュ値が参照されているうちに、確率Ｐ１でｙの値（動的番号）のビット長が３に縮められる。ｙのためにて空いている３ビット長の値（動的番号）が二分木（図６Ｂ（ｆ）を見よ）から探索されて、値（動的番号）010が求められる（図６Ａ（ｆ）を見よ）。現在のノードより下にはｙしかないので、ｘとｙの区別がつかなくなることはない。
【００７９】
（ｇ）同様に、ｘで多くのオブジェクトが割り付けられ、且つ該割り付けられたオブジェクトのが参照されているうちに、確率Ｐ２でｘの値（動的番号）のビット長が２に縮められる。ｘのために空いている２ビット長の値（動的番号）が二分木（図６Ｂ（ｇ）を見よ）から探索される。該探索の結果、値（動的番号）は10である（図６Ａ（ｇ）を見よ）。
【００８０】
上記二分木は、値（動的番号）から割り付け場所への対応表も兼ねることもできる。以下に、上記二分木からオブジェクトの割り付け場所を求める方法を示す。
コンピュータ・システムは、上記オブジェクトのハッシュ値を表すビットを左から順に取得する。コンピュータ・システムは、上記取得したビットに対応する二分木の枝を、ルートノードから取得した順に下降する。上記下降する過程で、割り付け場所が設定されているノードが見つかったならば、コンピュータ・システムは、上記割り付け場所を上記求める割り付け場所とする。
上記オブジェクトのハッシュ値が、例えば（１０１１）２ならば、コンピュータ・システムは、ルートノードから１に対応する枝、０に対応する枝、１に対応する枝、そして１に対応する枝の順に、二分木を下降する。ここで、例えば、左から１桁目の１に対応する枝を下った先にあるノードには、何も設定されていないとする。また、左から２桁目の０に対応する枝を下った先にあるノードには、割り付け場所が設定されているとする。上記例の場合、コンピュータ・システムは、左から２桁目の０に対応する枝を下った先にあるノードに設定されている割り付け場所を、求める割り付け場所とする。
【００８１】
コンピュータ・システムは、上記二分木からオブジェクトの割り付け場所を求めるために、戻された値（動的番号）のビットを使用してもよい。以下、戻された値（動的番号）のビットを説明する。
値（動的番号）はクラスごとにランダムな値にされるので、値（動的番号）とクラス固有の定数CLASS_HASHとの排他的論理和を取った値を値（動的番号）とする。上記割り付け場所を求める場合、上記オブジェクトのハッシュ値の入っているワードとCLASS_HASHとの排他的論理和が求められる。値（動的番号）は、排他的論理和が取られる前の値（動的番号）に戻される必要がある。なお、CLASS_HASHは、例えば、クラスオブジェクトのアドレスの一部であって、クラス固有のランダム値であるとする。該戻された値（動的番号）のビットを使用して、上記二分木からオブジェクトの割り付け場所が求められうる。
【００８２】
なお、上記図６Ａ及び図６Ｂの例では、割り付け場所ごとに直前に割り振ったノードから探索が開始される。ここで、高速化のために、ビット長ごとに直前に割り振られたノードを覚えておいて、次回は該割り振られたノードから探索が開始されてもよい。
【００８３】
図７は、本発明の実施態様における、指定された割り付け場所に指定されたビット長の新たな値（動的番号）を割り振る処理のフローチャートを示す。
上記フローチャートが実装される関数は、新たな値（動的番号）の割り振りが成功した場合はtrueを返し、失敗した場合はfalseを返す。
【００８４】
ステップ７０１では、コンピュータ・システムは、呼び出し元からの要求に応じて、上記関数を呼び出して処理を開始する。該処理が実行される関数の名前は、「Search_for_next_dynamic_ID」とする。また、該関数の入力は、割り付け場所及び該割り付け場所のビット長である。
ステップ７０２では、コンピュータ・システムは、入力で指定された割り付け場所の現在の値（動的番号）と入力で指定されたビット長とから二分木の対応するノードを得る。該ノードは、現在の値（動的番号）のビット列に左から入力で指定されたビット長だけマスクして取り出した番号に対応するノードである。該ノードを得ることに応じて、該処理はステップ７０３に進む。
ステップ７０３では、コンピュータ・システムは、上記得た現在のノードにいずれかの割り付け場所が設定されているかどうかを判定する。割り付け場所が設定されている場合、処理はステップ７０９に進む。割り付け場所が設定されていない場合、該処理はステップ７０４に進む。
ステップ７０４では、コンピュータ・システムは、現在のノードに子ノードがあるかを判定する。子ノードがある場合、処理はステップ７０５に進む。子ノードがない場合、該処理はステップ７０７に進む。
ステップ７０５では、コンピュータ・システムは、現在のノードに子ノードが２つあるかどうかを判定する。現在のノードに子ノードが２つある場合、該処理は、ステップ７０６に進む。現在のノードに子ノードが２つない場合、該処理は、７０６に進む。
ステップ７０６では、コンピュータ・システムは、現在のノードの子ノードには入力で指定された割り付け場所とは違う割り付け場所が設定されているかどうかを判定する。割り付け場所とは違う割り付け場所が設定されている場合、処理はステップ７０９に進む。割り付け場所と同じ割り付け場所が設定されている場合、該処理はステップ７０７に進む。
ステップ７０７では、コンピュータ・システムは、現在のノードに、入力で指定された割り付け場所を設定する。また、コンピュータ・システムは、入力で指定された割り付け場所の現在の値（動的番号）を更新する。該更新が終了すると、該処理はステップ７０８に進む。
ステップ７０８は、関数の終了である。ステップ７０８では、コンピュータ・システムは、関数が成功したことを示すtrueを関数の呼び出し元に返し、該処理は終了する。
ステップ７０９では、コンピュータ・システムは、現在のノードが、親ノードの“１”側の子ノードである限り、親ノードを現在のノードとしつつ木を上昇する。本発明の実施態様で使用される二分木では、枝は１又は０のビットで表す。親ノードの“１”側の子ノードであるとは、親ノードから見て１のビットで表される枝で繋がれた子ノードであることを示す。コンピュータ・システムは、現在のノードが親ノードの“１”側の子ノードである場合、親ノードを現在のノードとし、再帰的に“１”の枝を上昇する。該上昇は、現在のノードが、親ノードから見て１のビットで表される枝で繋がれた子ノードではなくなるまで繰り返され、該繰り返しが終了すると、該処理はステップ７１０に進む。
ステップ７１０では、コンピュータ・システムは、上記上昇によって求められた現在のノードの親のノードを現在のノードとする。該現在のノードが決定されたら、該処理はステップ７１１に進む。なお、親のノードが存在しない場合の処理は、次のステップ７１１で行われる。
ステップ７１１では、コンピュータ・システムは、ステップ７１０で親のノードを求める場合に、木のルートノードの上へさらにたどらなければならないかどうかを判定する。該判定により、木のルートノードの上へさらにたどらなければならない場合、該処理は、ステップ７１２に進む。木のルートノードの上へさらにたどらなくてもよい場合、該処理は、ステップ７１３に進む。
ステップ７１２では、コンピュータ・システムは、上記関数が失敗したことを示すfalseを関数の呼び出し元に返し、該処理は終了する。
ステップ７１３では、コンピュータ・システムは、ステップ７１０で決定された現在のノードから“１”側の子ノードへ一段階木を下降してから、“０”側の子ノードへ下降していく。該下降は、いずれかの割り付け場所が設定されているノードに到達するか、又は木の探索開始時点のノードと同じ高さのノードに到達するまで続けられる。ここで、木の探索開始時点のノードとは、ステップ７０２で得たノードである。また、上記下降において“０”側の子ノードがなく新たなノードが必要ならば、コンピュータ・システムは、二分木に新たなノードを生成する。該下降が終了したら、該処理は、ステップ７０３に戻る。
【００８５】
図８Ａ〜Ｆは、本発明の実施態様を実装する場合のプログラム・コードの例を示す。なお、上記プログラム・コードは一例に過ぎずこれに限定されるものではない。
【００８６】
図８Ａは、本発明の実施態様における、図２Ｂのハッシュ値フィールドのための定数定義を実装するプログラム例を示す。
プログラム・コード（８０１）は、１ワード＝３２ビットで、上位１４ビットがハッシュ値フィールドに用いられる実装例を示す。
プログラム・コード（８０１）では、ハッシュ値フィールドのビット長は１４に定義される。オブジェクト識別子が保存されるビットのビット長は、４〜１４ビットとなるように定義される。割り付け場所に対応した値が保存されるビットの最大ビット長は、ハッシュ値フィールドのビット長（１４ビット）から、オブジェクト識別子が保存されるビットのビット長のうち最小のビット（４ビット）を引いた長さのビット（１０ビット）に定義される。参照フラグが保存されるビットは、１８ビット目に設定される。なお、プログラム・コード（８０１）は、参照フラグをハッシュ値フィールドに含めない例を示す。
【００８７】
図８Ｂは、本発明の実施態様における、図２Ａのデータ構造を実装するためのプログラム例を示す。
プログラム・コード（８０２）は、図２Ａで示すオブジェクトを構造体で表した例を示す。
プログラム・コード（８０３）は、割り付け場所ごとの情報を保存するための構造体の例を示す。該構造体には、値（動的番号）及びオブジェクト識別子のビット長などの割り付け場所ごとに必要な情報が保存される。
【００８８】
図８Ｃは、本発明の実施態様における、図６Ｂの二分木に関するデータ構造を実装するためのプログラム例を示す。
プログラム・コード（８０４）は、図６Ｂで示す二分木のノードを構造体で表した例を示す。該構造体には、値（静的番号）、値（動的番号）及び他のノードとの関係などのノードごとに必要な情報が保存される。
プログラム・コード（８０５）は、図６Ｂで示す二分木を管理するための構造体の例を示す。該構造体は、クラスごとに用意され、二分木の排他制御及びルートノードについての情報が保存される。
【００８９】
図８Ｄ〜図８Ｆは、本発明の実施態様における、図４Ｂに示す、ハッシュ値を参照する関数に、ハッシュ値フィールドの値（静的番号）を値（動的番号）へと書き換えるアルゴリズムの組み込みを実装するためのプログラム例を示す。
上記関数では、呼び出し元にハッシュ値が返されるとともに、ハッシュ値が初めて参照されたならば、ハッシュ値フィールドの値（静的番号）が値（動的番号）へと書き換えられる。ここで、該書き換えは、原子的に実行される必要がある。
【００９０】
図９Ａは、本発明の実施態様における、値（静的番号）を埋め込んだ実行時オブジェクトのデータ構造を作成する方法、及び該データ構造を利用して、プログラム中のオブジェクトの割り付け場所を追跡するための方法のフロー図を示す。
ステップ９０１では、コンピュータ・システムは、オブジェクト割り付け場所に対応する値（静的番号）を実行時オブジェクトのハッシュ値フィールドに埋め込む方法を開始する。該開始は、上記プログラムにおけるオブジェクト割り付けに対応して、実行環境、例えばＪＶＭで実行時オブジェクトの生成を開始することに応じて行われる。
ステップ９０４では、コンピュータ・システムは、上記プログラム中のオブジェクト割り付け場所を例えばコンパイラを通じて取得する。
ステップ９０５では、コンピュータ・システムは、割り付け場所に対応する値（静的番号）がまだ生成されていない場合、割り付け場所に対応する値（静的番号）を生成する。該値（静的番号）は、ハッシュ値フィールドのビット長より短い固定のビット長を有する。
ステップ９０６では、コンピュータ・システムは、値（静的番号）と該値（静的番号）に対応する割り付け場所との対応付けを記録する対応表をメモリ内に格納する。なお、割り付け場所としてプログラムの行番号それ自体が用いられる場合、該対応表は不要である。
ステップ９０７では、コンピュータ・システムは、オブジェクト識別子を生成する。該オブジェクト識別子は、任意の方法で生成されうる。例えば、実行時オブジェクトを割り付けようとするアドレスを利用してもよい。
ステップ９０８では、コンピュータ・システムは、該値（静的番号）及びオブジェクト識別子を実行時オブジェクトのハッシュ値フィールドに埋め込む。
ステップ９０９では、コンピュータ・システムは、埋め込みを終了する。その後、所望のデータ構造を備えた実行時オブジェクトが、実行環境、例えばＪＶＭで生成され、メモリ内に割り当てられる。
ステップ９１０では、コンピュータ・システムは、プログラム中のオブジェクトの割り付け場所の追跡を開始する。該追跡は、上記プログラムを実行して、上記プログラムの実行途中又は実行終了後に、追跡開始の指示がコンピュータ・システムに与えられることによって開始される。
ステップ９１１では、コンピュータ・システムは、ヒープ領域に残存している実行時オブジェクトのハッシュ値フィールドから、埋め込まれた値（静的番号）を取得する。
ステップ９１２では、コンピュータ・システムは、対応表を参照して、上記取得した値（静的番号）に対応するオブジェクトの割り付け場所を特定する。
ステップ９１２及びステップ９１１は、残存している全ての実行時オブジェクトに対して行われる。ステップ９１２及びステップ９１１は、ユーザによって指定された実行時オブジェクトに対して行われてもよい。コンピュータ・システムは、各オブジェクトと上記特定された割り付け場所との対応を、画面上に表示し、又はファイルとして出力する。
ステップ９１３では、コンピュータ・システムは、上記追跡を終了する。
なお、ステップ９０５で、値（静的番号）が行番号それ自体である場合は、ステップ９０６の対応表は不要である。また、ステップ９０７において、オブジェクト識別子を生成せず、実行環境で生成されるハッシュ値を表すビットのうち、値（静的番号）で置き換えられなかったビットで表される値をオブジェクト識別子として使ってもよい。
【００９１】
図９Ｂは、本発明の実施態様における、値（動的番号）を埋め込んだ実行時オブジェクトのデータ構造を作成する方法、及び該データ構造を利用して、プログラム中のオブジェクトの割り付け場所を追跡するための方法のフロー図を示す。
ステップ９２１では、コンピュータ・システムは、オブジェクト割り付け場所に対応する値（動的番号）を実行時オブジェクトのハッシュ値フィールドに埋め込む方法を開始する。該開始は、上記プログラムにおけるオブジェクト割り付けに対応して、実行環境、例えばＪＶＭで実行時オブジェクトの生成を開始することに応じて行われる。
ステップ９２４では、コンピュータ・システムは、上記プログラム中のオブジェクト割り付け場所を例えばコンパイラを通じて取得する。
ステップ９２５では、コンピュータ・システムは、割り付け場所に対応する値（動的番号）が対応表に記録されていない場合又は同一の割り付け場所について値（動的番号）のビット長を変更する場合、割り付け場所に対応する値（動的番号）を生成する。該値（動的番号）は、ハッシュ値フィールドのビット長より短いビット長を有する。値（動的番号）では、最初は該値のビット長は比較的長く設定される。そして、同じオブジェクトで同じ割り付け場所に割り付けられ数が増えることに応じて、該値（動的番号）のビット長は次第に短く設定される。
ステップ９２６では、コンピュータ・システムは、値（動的番号）と該値（動的番号）に対応する割り付け場所との対応付けを記録する対応表をメモリ内に格納する。なお、値（動的番号）のビット長が次第に短く設定される場合、それに応じて同じ割り付け場所に複数の値（動的番号）が対応する対応表が作成される。
ステップ９２７では、コンピュータ・システムは、オブジェクト識別子を生成する。該オブジェクト識別子は、任意の方法で生成されうる。例えば、実行時オブジェクトを割り付けようとするアドレスを利用してもよい。
ステップ９２８では、コンピュータ・システムは、値（動的番号）及びオブジェクト識別子を実行時オブジェクトのハッシュ値フィールドに埋め込む。
ステップ９２９では、コンピュータ・システムは、埋め込みを終了する。その後、所望のデータ構造を備えた実行時オブジェクトが、実行環境、例えばＪＶＭで生成され、メモリ内に割り当てられる。
ステップ９３０では、コンピュータ・システムは、プログラム中のオブジェクト割り付け場所の追跡を開始する。該追跡は、上記プログラムを実行して、上記プログラムの実行途中又は実行終了後に、追跡開始の指示がコンピュータ・システムに与えられることによって開始される。
ステップ９３１では、コンピュータ・システムは、ヒープ領域に残存している実行時オブジェクトのハッシュ値フィールドから、埋め込まれた値（動的番号）を取得する。
ステップ９３２では、コンピュータ・システムは、対応表を参照して、上記取得した値（動的番号）に対応するオブジェクトの割り付け場所を特定する。
ステップ９３２及びステップ９３１は、残存している全ての実行時オブジェクトに対して行われる。ステップ９３２及びステップ９３１は、ユーザによって指定された実行時オブジェクトに対して行われてもよい。コンピュータ・システムは、各オブジェクトと上記特定された割り付け場所との対応を、画面上に表示し、又はファイルとして出力する。
ステップ９３３では、コンピュータ・システムは、上記追跡を終了する。
【００９２】
図９Ｃは、本発明の実施態様における、値（静的番号）及び値（動的番号）をとも使用した実行時オブジェクトのデータ構造を作成する方法、及びそのデータ構造を利用してオブジェクトの割り付け場所を追跡するための方法のフロー図を示す。
ステップ９４１では、コンピュータ・システムは、オブジェクト割り付け場所に対応する値（静的番号）を実行時オブジェクトのハッシュ値フィールドに埋め込む方法を開始する。該開始は、上記プログラムにおけるオブジェクト割り付けに対応して、実行環境、例えばＪＶＭで実行時オブジェクトの生成を開始することに応じて行われる。
ステップ９４２では、コンピュータ・システムは、図９Ａのステップ９０４〜９０６の処理を実行する。次に、コンピュータ・システムは、値（静的番号）及び参照フラグをハッシュ値フィールドに埋めこむ。その後、実行時オブジェクトが実行環境、例えばＪａｖａ（商標）言語で生成され、メモリ内に割り当てられる。
ステップ９４３では、上記生成されたオブジェクトへの参照が初めて行われると、コンピュータ・システムは、該オブジェクトのハッシュ値フィールドを置き換える動作を開始する。
ステップ９４４では、コンピュータ・システムは、置き換え対象オブジェクトのハッシュ値フィールドに保持されている値（静的番号）を取得する。
ステップ９４５では、コンピュータ・システムは、割り付け場所に対応する値（動的番号）を生成する。該値（動的番号）は、ハッシュ値フィールドのビット長より短いビット長を有する。値（動的番号）では、最初は該値のビット長は比較的長く設定される。そして、同じオブジェクトで同じ割り付け場所に割り付けられ数が増えることに応じて、該値（動的番号）のビット長は次第に短く設定される。
ステップ９４６では、コンピュータ・システムは、該値（動的番号）と該値（動的番号）に対応する割り付け場所との対応付けを記録する対応表をメモリ内に格納する。なお、値（動的番号）のビット長が次第に短く設定される場合、それに応じて同じ割り付け場所に複数の値（動的番号）が対応する対応表が作成される。
ステップ９４７では、コンピュータ・システムは、オブジェクト識別子を生成する。該オブジェクト識別子は、任意の方法で生成されうる。例えば、実行時オブジェクトを割り付けようとするアドレスを利用してもよい。
ステップ９４８では、コンピュータ・システムは、値（動的番号）及びオブジェクト識別子を実行時オブジェクトのハッシュ値フィールドに埋め込む。またコンピュータ・システムは、実行時オブジェクトのハッシュ値フィールドの参照フラグを立てる。
ステップ９４９では、コンピュータ・システムは、埋め込みを終了する。その後、所望のデータ構造を備えた実行時オブジェクトが、実行環境、例えばＪＶＭで生成され、メモリ内に割り当てられる。
ステップ９５０では、コンピュータ・システムは、プログラム中のオブジェクト割り付け場所の追跡を開始する。該追跡は、上記プログラムを実行して、上記プログラムの実行途中又は実行終了後に、追跡開始の指示がコンピュータ・システムに与えられることによって開始される。
ステップ９５１では、コンピュータ・システムは、ヒープ領域に残存している実行時オブジェクトのハッシュ値フィールドから、埋め込まれた値（動的番号）を取得する。
ステップ９５２では、コンピュータ・システムは、対応表を参照して、上記取得した値（動的番号）に対応するオブジェクトの割り付け場所を特定する。
ステップ９５２及びステップ９５１は、残存している全ての実行時オブジェクトに対して行われる。ステップ９５２及びステップ９５１は、ユーザによって指定された実行時オブジェクトに対して行われてもよい。コンピュータ・システムは、各オブジェクトと上記特定された割り付け場所との対応を、画面上に表示し、又はファイルとして出力する。
ステップ９５３では、コンピュータ・システムは、上記追跡を終了する。
【００９３】
本発明の実施態様では、コンピュータ・システムは、上記値（静的番号）又は値（動的番号）を回収して再使用しうる。該再使用の手順を以下に述べる。
コンピュータ・システムは、定期的にヒープ領域をスキャンする。該スキャンは、例えば、ガーベジコレクションが実行されることに応じて実行されてもよい。ガーベジコレクションが実行されることに応じて該スキャンが実行されることにより、コンピュータ・システムは、システムにかかる負荷を低く抑えることができる。また、上記スキャンは、プログラム・コード上の実行頻度の低い割り付け場所で割り付けられるオブジェクトに対してのみ行われてもよい。
上記スキャンでは、コンピュータ・システムは、割り付けられた全てのオブジェクトが生きていない割り付け場所に対応する値（静的番号）及び値（動的番号）を取得する。また、コンピュータ・システムは、割り付けられた全てのオブジェクトに値（動的番号）が埋め込まれている割り付け場所に対応する値（静的番号）を取得してもよい。
コンピュータ・システムは、上記取得した値（静的番号）及び値（動的番号）を、例えば対応表に記録する。
コンピュータ・システムは、新たな割り付け場所で実行時オブジェクトが割り付けられた場合、上記記録された値（静的番号）を新たな割り付け場所に対応する値（静的番号）として使用しうる。
また、コンピュータ・システムは、上記新たな割り付け場所で実行時オブジェクトのハッシュ値が参照された場合、上記記録された値（動的番号）を上記新たな割り付け場所に対応する値（動的番号）として使用しうる。
【００９４】
コンピュータ・システムは、上記取得された値（静的番号）又はそれに対応する割り付け場所で新たにオブジェクトが割り付けられた場合、新たな値（静的番号）又は「その他」を表す特別な値を上記取得された値（静的番号）に対応する割り付け場所に割り振る。コンピュータ・システムは、上記割り振られた値を、例えば対応表に記録する。
また、コンピュータ・システムは、上記取得された値（動的番号）に対応する割り付け場所で新たに割り付けられたオブジェクトのハッシュ値が参照された場合、新たな値（動的番号）又は「その他」を表す特別な値を上記取得された値に対応する割り付け場所に割り振る。コンピュータ・システムは、上記割り振られた値を、例えば対応表に記録する。
【００９５】
値（静的番号）が足りなくなった場合、コンピュータ・システムは、同じメソッド中の割り付け場所を同じ値（静的番号）になるように割り振り直し、そしてオブジェクト・ヘッダに埋め込まれている値（静的番号）を上記割り振り直された同じ値（静的番号）に書き換えてもよい。
【００９６】
図１０は、本発明の実施態様における、図９Ａ〜図９Ｃで示す、オブジェクトの割り付け場所の追跡結果の出力例を示す。
あるプログラムを実行するとヒープ領域の使用量が無制限に増えていくバグが発見されたとする。該出力例は、該あるプログラムを実行中のある時点において、ヒープ領域にある実行時オブジェクトのメモリ内アドレスと、該プログラム中の割り付け場所の一覧を表示させたものである。該出力から、例えば、最も多くのオブジェクトを割り付けている場所を知ることができる。本出力例では、メソッドmeth2の行番号１２８に割り付けられたオブジェクトの数が非常に多いことが分かる。これによって、例えばヒープ領域の使用量が無制限に増加していくバグの原因が、メソッドmeth2の行番号１２８にある可能性が高いことが推定される。このように、オブジェクトの割り付け場所を追跡可能にすることで上記バグの原因が見つけることができ、結果としてプログラムの信頼性が上がる。
【００９７】
図１１は、本発明の実施態様における、２つのアプリケーション（Trade 6及びSPECjbb2005）における、クラスごとの割り付け場所の静的な数を示す。
図９Ａ〜図９Ｃに示す方法を実装したシミュレータを使用して、下記の実験を行った。
実験では、まずＪａｖａ（商標）仮想マシン（Ｊａｖａ  ＶＭ）に対してＪＶＭＴＩ（商標）（Java Virtual Machine Tool Interface）を用い、実行時オブジェクトの割り付け及びjava.lang.Object.hashCode()の呼び出しのトレースを取った。なお、java.lang.System.identityHashCode()の呼び出しのトレースは取っていない。また、hashCode()をオーバーライドしているクラス、例えば、java.lang.String、 java.lang.Integerのオブジェクトに対する呼び出しは、上記トレースの対象から除外している。次にトレースをシミュレータに入力して、割り付け場所の数及び本発明の実施態様によるハッシュ値の衝突の数を調べた。実験で用いられた実装は、オブジェクト識別子を表すビットの下半分のビットが０になったタイミングで新たな値（動的番号）を割り振ること以外は、上で示した擬似コードと同等の実装である。また、１５ビット長のランダムな値をハッシュ値として用いた場合と値（静的番号）をそのままハッシュ値として用いた場合との衝突の数も調べた。アプリケーションとしてSPECjbb2005を1 warehouseで２分間動かした場合とWebSphere Application Server 6.1を起動開始からTrade6を動かして２分間負荷をかけた場合とを調べた。
図１１に示す数はバイトコード中の割り付け場所の数であり、ＪＶＭ中でStringリテラルなどを割り付けている場所の数は含まれない。最も多い割り付け場所の数はTrade6においてObjectクラスの配列の14933箇所であった。これは１４ビットで表せる数であり、本実験で値（静的番号）があふれることは無かった。
【００９８】
図１２は、本発明の実施態様における、図１１で使用した２つのアプリケーション（Trade 6,SPECjbb2005）における、ハッシュ値の平均衝突数と最大衝突数を示す。
衝突数とは、あるハッシュ値を持つオブジェクトの数であり、全てのオブジェクトが異なるハッシュ値を持つならば衝突数は１である。現実のプログラムでは異なるクラスのオブジェクトのハッシュ値が比較されることは少ないことから、本実験では同じクラスのオブジェクトの間のみで衝突を調べた。また、オブジェクトの生存期間は考慮していないので、同時に生きていないオブジェクトの間で起きた衝突もカウントしている。図１２に示す実験結果より、本発明の実施態様による衝突は十分に少なく実用的である。
本実験では、新たな動的番号を割り振れないケースがTrade 6で１５回起きた。上記ケースのいずれにおいても、何らかの値（動的番号）が既に割り振られている割り付け場所に新たな動的番号を割り振ろうとして失敗したケースであった。図８Ａ〜図８Ｆのプログラムに示したように、このように失敗したケースでは既に割り振られた値（動的番号）を使い続けるので、割り付け場所情報の曖昧さは生じない。
【００９９】
図１３Ａ〜図１３Ｄは、本発明の実施態様における、図４Ｂ、図７及び図９に示す処理を実行するコンピュータ・システムの有する機能を図示する機能ブロック図を示す。
【０１００】
図１３Ａは、本発明の実施態様における、図９Ａ〜図９Ｃで示す、プログラムを追跡する処理を実行するコンピュータ・システムの有する機能を図示する機能ブロック図を示す。
コンピュータ・システム（１３００）は、記憶部（１３０１）、ＣＰＵ（１３０４）、メモリ（１３０５）、取得部（１３２０）及び特定部（１３２１）を含む。記憶部（１３０１）は、コンピュータ・システム（１３００）の内部にあっても外部にあってもよい。記憶部（１３０１）はまた、コンピュータ・システム（１３００）に接続されているネットワーク上の記憶装置又は他のコンピュータ・システム内にある記憶装置であってもよい。記憶部（１３０１）は、追跡されるプログラム（１３０２）を格納する。記憶部（１３０１）は、第２の対応表（１３０３）を格納してもよい。
ＣＰＵ（１３０３）は、図９Ａ〜図９Ｃで示す追跡する処理を実行する。ＣＰＵ（１３０３）は、第２の対応表（１３０３）が記憶部（１３０１）に格納されているならば、該実行に応じて、第２の対応表（１３０３）をメモリ（１３０５）内に読み込む。
メモリ（１３０５）は、ヒープ領域（１３０６）を含む。メモリ（１３０５）には、記憶部（１３０１）から読み込まれた追跡されるプログラム（１３０２）、及び任意的に第１の対応表（１３１０）及び第２の対応表（１３１０）が保持されている。また、ヒープ領域（１３０６）には、メモリ（１３０５）に読み込まれた追跡されるプログラム（１３０２）によって、実行時オブジェクト（１３０７〜１３０９）が割り付けられている。
取得部（１３２０）は、実行時オブジェクト（１３０７〜１３０９）のハッシュ値フィールドから、プログラム中のオブジェクトの割り付け場所に対応した値を取得する。
特定部（１３２１）は、上記取得した値から割り付け場所を特定する。該特定には、第１の対応表（１３１０）、第２の対応表（１３０３）又はそれらの組み合わせが使用されてもよい。
【０１０１】
図１３Ｂは、本発明の実施態様における、図４Ｂ、図７及び図９で示す、ハッシュ値フィールドに保持されている値（静的番号）を値（動的番号）に置き換える処理を実行するコンピュータ・システムの有する機能を図示する機能ブロック図を示す。
置換部（１３２２）、作成部（１３２３）及び調整部（１３２４）以外の機能ブロックは、図１３Ａのそれらと同じである。
ＣＰＵ（１３０４）は、図９Ｂ及び図９Ｃで示す処理を実行する。ＣＰＵ（１３０４）は、追跡されるプログラム（１３０１）を記憶部（１３０１）からメモリ（１３０２）に読み出す。ＣＰＵ（１３０４）は、追跡されるプログラム（１３０１）を実行する。該実行により、ヒープ領域（１３０６）には、実行時オブジェクト（１３０７〜１３０９）が割り付けられる。
置換部（１３２２）は、実行時オブジェクト（１３０７〜１３０９）のハッシュ値を参照する命令が初めて実行されることに応じて、実行時オブジェクト（１３０７〜１３０９）が有する値及びオブジェクト識別子を、新たな値及び新たなオブジェクト識別子に置換する。さらに、上記実行時オブジェクト１３０７〜１３０９が参照フラグを有する場合、置換部（１３２２）は、参照フラグを立てる。
作成部（１３２３）は、上記値と上記新たな値との対応を第１の対応表（１３１０）に保存する。
調整部（１３２４）は、プログラム中のオブジェクトの割り付け場所が同一である実行時オブジェクト（１３０７〜１３０９）が多く初めて参照されることに応じて、上記割り付け場所が同一である実行時オブジェクト（１３０７〜１３０９）の値に割り当てられるビット長を短くし、一方オブジェクト識別子に割り当てられるビット長を長くする。
【０１０２】
図１３Ｃは、本発明の実施態様における、図９Ａ〜図９Ｃで示す、ハッシュ値フィールドに値（静的番号）を埋め込む処理を実行するコンピュータ・システムの有する機能を図示する機能ブロック図を示す。
埋込部（１３２５）以外の機能ブロックは、図１３Ａ及び図１３Ｂのそれと同じである。
ＣＰＵ（１３０４）は、図９Ａで示す処理を実行する。ＣＰＵ（１３０４）は、追跡されるプログラム（１３０１）を記憶部（１３０１）からメモリ（１３０２）に読み出す。ＣＰＵ（１３０４）は、追跡されるプログラム（１３０１）を実行する。該実行により、ヒープ領域（１３０６）には、実行時オブジェクト（１３０７〜１３０９）が割り付けられる。
埋込部（１３２５）は、実行時オブジェクト（１３０７〜１３０９）のメモリへの割り付けに応じて、実行時オブジェクト（１３０７〜１３０９）のハッシュ値フィールドに、追跡されるプログラム（１３０２）中のオブジェクトの割り付け場所に対応した値及びオブジェクト識別子を埋め込む。埋込部（１３２５）は、実行時オブジェクト（１３０７〜１３０９）のハッシュ値フィールドに、さらに参照フラグを埋め込んでもよい。
調整部（１３２４）は、プログラム中のオブジェクトの割り付け場所が同一である実行時オブジェクト（１３０７〜１３０９）が多く割り付けられることに応じて、上記割り付け場所が同一である実行時オブジェクト（１３０７〜１３０９）の値に割り当てられるビット長を短くし、一方オブジェクト識別子に割り当てられるビット長を長くする。
【０１０３】
図１３Ｄは、本発明の実施態様における、使われていない実行時オブジェクトのハッシュ値フィールドの値を別の実行時オブジェクトの値とする処理を実行するコンピュータ・システムの有する機能を図示する機能ブロック図を示す。
埋込部（１３２５）以外の機能ブロックは、図１３Ａ〜図１３Ｃのそれと同じである。
ＣＰＵ（１３０４）は、追跡されるプログラム（１３０１）を記憶部（１３０１）からメモリ（１３０２）に読み出す。ＣＰＵ（１３０４）は、追跡されるプログラム（１３０１）を実行する。該実行により、ヒープ領域（１３０６）には、実行時オブジェクト（１３０７〜１３０９）が割り付けられる。ここで、実行時オブジェクト１（１３０７）は、使われていない実行時オブジェクトとする。また。実行時オブジェクト２（１３０８）は、値が不足しているため、ハッシュ値フィールドに値が保持されなかった実行時オブジェクトとする。
再利用部（１３２６）は、ヒープ領域（１３０６）をスキャンし、使われていない実行時オブジェクト２（１３０８）のハッシュ値フィールドから値を取得する。再利用部（１３２６）は、実行時オブジェクト２（１３０８）のハッシュ値フィールドに上記取得した値を埋め込む。
実行が進むにつれて新たに割り付け場所に対応した値を割り振っていくと、値（静的番号）又は値（動的番号）のビット長が足りなくなる可能性がある。そこで、再利用部（１３２６）は、実行頻度が低い割り付け場所の番号又はヒープ領域をスキャンし、生きているオブジェクトがない値（静的番号）又は値（動的番号）を回収して使いまわしてもよい。
同じ場所で割り付けられ且つ生きている実行時オブジェクトには全て値（動的番号）が埋め込まれている。そこで、再利用部（１３２６）はまた、上記実行時オブジェクトに埋め込まれていた値（静的番号）を回収してもよい。ヒープ領域のスキャンがガーベジコレクションとともに行われれば、追跡されるプログラムのオーバーヘッドは少なくて済む。
【０１０４】
図１４は、本発明の実施態様における、図１３に示すコンピュータ・ハードウェアのブロック図を示す。
コンピュータ・システム（１４０１）は、ＣＰＵ（１４０２）とメイン・メモリ（１４０３）と含み、これらはバス（１４０４）に接続されている。ＣＰＵ（１４０２）は好ましくは、３２ビット又は６４ビットのアーキテクチャに基づくものであり、例えば、インテル社のＸｅｏｎ（商標）シリーズ、Ｃｏｒｅ（商標）シリーズ、Ａｔｏｍ（商標）シリーズ、Ｐｅｎｔｉｕｍ（商標）シリーズ、Ｃｅｌｅｒｏｎ（商標）シリーズ、ＡＭＤ社のＰｈｅｎｏｍ（商標）シリーズ、Ａｔｈｌｏｎ（商標）シリーズ、Ｔｕｒｉｏｎ（商標）シリーズ及びＳｅｍｐｒｏｎ（商標）などを使用することができる。バス（１４０４）には、ディスプレイ・コントローラ（１４０５）を介して、ＬＣＤモニタなどのディスプレイ（１４０６）が接続される。ディスプレイ（１４０６）は、コンピュータ・システムの管理のために、通信回線を介してネットワークに接続されたコンピュータ・システムについての情報と、そのコンピュータ・システム上で動作中のソフトウェアについての情報を、適当なグラフィック・インターフェースで表示するために使用される。バス（１４０４）にはまた、ＩＤＥ又はＳＡＴＡコントローラ（１４０７）を介して、ハードディスク又はシリコン・ディスク（１４０８）と、ＣＤ−ＲＯＭ、ＤＶＤドライブ又はＢＤドライブ（１４０９）が接続される。
【０１０５】
ハードディスク（１４０８）には、オペレーティング・システム、Ｊ２ＥＥなどのＪａｖａ（商標）処理環境を提供するプログラム、その他のプログラム及びデータが、メイン・メモリにロード可能に記憶されている。
【０１０６】
ＣＤ−ＲＯＭ、ＤＶＤ又はＢＤドライブ（１４０９）は、必要に応じて、ＣＤ−ＲＯＭ、ＤＶＤ−ＲＯＭ又はＢＤからプログラムをハードディスクに追加導入するために使用される。バス（１４０４）には更に、キーボード・マウスコントローラ（１４１０）を介して、キーボード（１４１１）及びマウス（１４１２）が接続されている。
【０１０７】
通信インタフェース（１４１４）は、例えばイーサネット（商標）・プロトコルに従う。通信インタフェース（１４１４）は、通信コントローラ（１４１３）を介してバス（１４０４）に接続され、コンピュータ・システム及び通信回線（１４１５）を物理的に接続する役割を担い、コンピュータ・システムのオペレーティング・システムの通信機能のＴＣＰ／ＩＰ通信プロトコルに対して、ネットワーク・インターフェース層を提供する。なお、通信回線は、有線ＬＡＮ環境、或いは例えばＩＥＥＥ８０２．１１ａ／ｂ／ｇ／ｎなどの無線ＬＡＮ接続規格に基づく無線ＬＡＮ環境であってもよい。
【図１】
2010204955.tif 000003
【図２Ａ】
2010204955.tif 000004
【図２Ｂ】
2010204955.tif 000005
【図３】
2010204955.tif 000006
【図４Ａ】
2010204955.tif 000007
【図４Ｂ】
2010204955.tif 000008
【図４Ｃ】
2010204955.tif 000009
【図４Ｄ】
2010204955.tif 000010
【図５】
2010204955.tif 000011
【図６Ａ】
2010204955.tif 000012
【図６Ｂ】
2010204955.tif 000013
【図７】
2010204955.tif 000014
【図８Ａ】
2010204955.tif 000015
【図８Ｂ】
2010204955.tif 000016
【図８Ｃ】
2010204955.tif 000017
【図８Ｄ】
2010204955.tif 000018
【図８Ｅ】
2010204955.tif 000019
【図８Ｆ】
2010204955.tif 000020
【図９Ａ】
2010204955.tif 000021
【図９Ｂ】
2010204955.tif 000022
【図９Ｃ】
2010204955.tif 000023
【図１０】
2010204955.tif 000024
【図１１】
2010204955.tif 000025
【図１２】
2010204955.tif 000026
【図１３Ａ】
2010204955.tif 000027
【図１３Ｂ】
2010204955.tif 000028
【図１３Ｃ】
2010204955.tif 000029
【図１３Ｄ】
2010204955.tif 000030
【図１４】
2010204955.tif 000031