(57)【特許請求の範囲】
【請求項１】
メソッド中で生じ得るメソッド呼び出しに関する呼び出しマップと実際に生じたメソッド呼び出しに関する情報とが各メソッドごとに記録されている場合に、あるメソッドが実行される可能性の高低を表す活動度を計算する方法であって、
スタックの各フレームに対応する各第１メソッドについての、各第１メソッドから呼ばれる可能性があるメソッドを、前記呼び出しマップに基づいて特定し、その中で、実際に呼ばれたことがあるメソッドを前記実際に生じたメソッド呼び出しに関する情報に基づいて抽出し、これを呼ばれる可能性が高い各第２メソッドとして特定し且つ記憶装置に格納し、前記各第１メソッドに対応するスタックフレームのスタックの最上部からの段数に応じた優先度を前記各第２メソッドの活動度に作用することにより前記各第２メソッドの活動度を更新するメソッド活動度計算方法。
【請求項２】
前記各第２メソッドについて、前記各第２メソッドから呼ばれる可能性があるメソッドを、前記呼び出しマップに基づいて特定し、その中で、実際に呼ばれたことがあるメソッドを「実際に生じたメソッド呼び出しに関する情報」に基づいて抽出し、これを呼ばれる可能性が高い各第３メソッドとして特定し且つ記憶装置に格納し、前記各第１メソッドに対応するスタックフレームのスタックの最上部からの段数に応じた優先度を前記各第３メソッドの活動度に作用することにより前記各第３メソッドの活動度を更新する請求項１記載のメソッド活動度計算方法。
【請求項３】
前記呼び出しマップが、前記メソッド中のあるアドレスに対し、当該アドレス以降に生じ得るメソッド呼び出しを出力するように構成され、前記各第２メソッドの特定は、前記各第１メソッドの実行再開アドレス以降に生じ得るメソッド呼び出しを用いて行われる請求項１記載のメソッド活動度計算方法。
【請求項４】
メソッド中で生じ得るメソッド呼び出しに関する呼び出しマップと実際に生じたメソッド呼び出しに関する情報とが各メソッドごとに記録されている場合に、あるメソッドが実行される可能性の高低を表す活動度を計算する装置であって、
スタックフレームに対応する各第１メソッドについて、各第１メソッドから呼ばれる可能性があるメソッドを、前記呼び出しマップに基づいて特定し、その中で、実際に呼ばれたことがあるメソッドを前記実際に生じたメソッド呼び出しに関する情報に基づいて抽出し、これを呼ばれる可能性が高い各第２メソッドとして特定し且つ記憶装置に格納する手段と、前記各第１メソッドに対応するスタックフレームのスタックの最上部からの段数に応じた優先度を前記各第２メソッドの活動度に作用することにより前記各第２メソッドの活動度を更新する手段とを有するメソッド活動度計算装置。
【請求項５】
メソッド中で生じ得るメソッド呼び出しに関する呼び出しマップと実際に生じたメソッド呼び出しに関する情報とが各メソッドごとに記録されている場合に、あるメソッドが実行される可能性の高低を表す活動度を計算するためのプログラムを格納した記憶媒体であって、
前記プログラムは、コンピュータに、
スタックフレームに対応する各第１メソッドについて、各第１メソッドから呼ばれる可能性があるメソッドを、前記呼び出しマップに基づいて特定し、その中で、実際に呼ばれたことがあるメソッドを前記実際に生じたメソッド呼び出しに関する情報に基づいて抽出し、これを呼ばれる可能性が高い各第２メソッドとして特定し且つ記憶装置に格納する機能と、前記各第１メソッドに対応するスタックフレームのスタックの最上部からの段数に応じた優先度を前記各第２メソッドの活動度に作用することにより前記各第２メソッドの活動度を更新する機能と
を実現させるためのプログラム
を記録した、記憶媒体。
【発明の詳細な説明】
【０００１】
【発明の属する技術分野】
本発明は、コード破棄するメソッドを効果的に選択するためのメソッド活動度計算方法に関係し、特に、Ｊａｖａ（Ｓｕｎ  Ｍｉｃｒｏｓｙｓｔｅｍｓ社の商標）のＪＩＴ（Ｊｕｓｔ  Ｉｎ  Ｔｉｍｅ）コンパイラにおけるメソッド活動度計算方法に関係する。
【０００２】
【従来の技術】
現在、Ｊａｖａは、ネットワークコンピューティングの共通言語としてだけでなく、プラットフォームに依存しない、オブジェクト指向言語のスタンダードな言語として広く使用されている。Ｊａｖａで書かれたプログラムはバイトコードに変換され、バイトコードはＪａｖａ仮想マシンで実行される。そのため、一度Ｊａｖａで書かれたプログラムは、Ｊａｖａをサポートしているコンピュータならば、ＣＰＵを問わずどこでも動く（マルチプラットフォーム）という利点を持つ。
【０００３】
しかしこうした利点の反面、バイトコードの仮想マシンによる実行は、機械語のコードを直接実行するのに比べて、実行性能の点で劣る。そのため、ＪＩＴコンパイラにより、Ｊａｖａプログラムの動作中に前記バイトコードを機械語コード（以下、ＪＩＴｅｄコードと呼ぶ）に変換して、バイトコードの代わりにＪＩＴｅｄコードを実行するのが一般的である。コンパイルの最小単位は、メソッドと呼ばれるサブルーチンである。実行頻度の高いコードを機械語に変換することにより、Ｊａｖａバイトコードのマルチプラットフォーム特性を残しつつ、機械語コードの性能を引き出している。
【０００４】
メソッドのＪＩＴｅｄコードは、プログラムが動作するＣＰＵに適したコードになっているという点で、Ｃコンパイラなどが生成する最適化コードと同等である。一般に、現在普及しているＣＰＵでは、サブルーチンが呼ばれると、サブルーチンは、自分が使用するローカル変数を格納するための領域（フレームと呼ぶ）をスタック状に形成する。図１は、サブルーチンＡがサブルーチンＢを、サブルーチンＢがサブルーチンＣを呼び出したときのスタックの様子である。この図において、スタックは下から上に伸びる。各領域は、サブルーチンのそれぞれのフレームを表わす。各サブルーチンから戻る際、フレームは除去される。Ｊａｖａでは、スレッドと呼ばれる実行単位毎にＣＰＵ資源が割り振られ、１つのスレッドは固有のスタック（スレッドスタックと呼ぶ）を持つ。ＪＩＴｅｄコードは、スレッドスタック上に上述したようなフレーム（以下、ＪＩＴｅｄフレームと呼ぶ）を作る。
【０００５】
メソッドは、最初ほとんどの場合インタプリタで実行されるが、実行頻度あるいは実行時間においてある水準以上実行されると判断されると、ＪＩＴコンパイラによりコンパイルされる。ＪＩＴｅｄコードは一度生成されると、メモリ中に管理される。それらを安全に捨てることができるということＪａｖａシステムが保証する時期は、Ｊａｖａシステムがガベージコレクション（以下、ＧＣ）によってクラスを破棄する（以下、クラスアンロード）ときである。
【０００６】
ＪＩＴｅｄコードを含むＪＩＴコンパイラが使用するメモリに制限がある、あるいは制限を設けるとき、クラスアンロードだけでは十分ではない場合がある。例えば、ハードディスクによる仮想記憶を持たない、ネットワークコンピューティング（Ｎｅｔｗｏｒｋ  Ｃｏｍｐｕｔｉｎｇ）マシン（以下、ＮＣマシン）のような、シンクライアント（ｔｈｉｎ  ｃｌｉｅｎｔ）上で動作するデスクトップ環境では、メモリ制限は現実的な問題である。そのようなデスクトップ環境では、メール、ワープロ、スケジューラ等、複数のＪａｖａアプリケーションが同時に起動され、数千種類のメソッドが呼ばれうるが、かなりの割合のメソッドが各スレッドスタック中に存在しない（アクティブでない）。クラスアンロードは、Ｊａｖａシステム内に完全に使用される可能性のないクラスおよびそのメソッドしか破棄しないため、そうしたアクティブでないメソッドのＪＩＴｅｄコードを破棄しない。そこでＪＩＴコンパイラはＪＩＴｅｄコード破棄メカニズムを持っている。
【０００７】
実行中のスレッドの現在のコンテキスト（プログラムカウンタ（ｐｒｏｇｒａｍ  ｃｏｕｎｔｅｒ）やスタックポインタ（ｓｔａｃｋ  ｐｏｉｎｔｅｒ）などＣＰＵ資源のコピー）あるいはそのスレッドスタック中に保持されるＪＩＴｅｄコードのフレームには、そのスレッドでのアクティブなメソッドが記録されている。アクティブなメソッドのＪＩＴｅｄコードが破棄されると、スレッドが実行できない。したがって、破棄するのは、非アクティブなＪＩＴｅｄコードである。ＪＩＴｅｄコード破棄メカニズムにおいて最も簡単な破棄の仕方は、アクティブでないＪＩＴｅｄコードをすべて破棄する方法である。しかし、この方法では必要以上にＪＩＴｅｄコードを破棄してしまい、無駄である。メソッドの最適化コンパイルには時間がかかるため、「すぐに実行されるメソッドを破棄しない」という方針の下で選択的に破棄すべきである。的確な選択の効果の例として、ＪＩＴｅｄコード破棄が今行われ、すぐに実行されるメソッドＡと、１０分後に実行されるメソッドＢがあったとする。もしＡを破棄すると、今破棄したＡのＪＩＴｅｄコードのメモリ量と、さらにＡのコンパイルに必要なワークのメモリ量とを、直ちに確保しなければならない。一方、Ｂを破棄すれば、１０分間はＢのＪＩＴｅｄコードのメモリ量は、利用可能メモリとなる。実際には必要なフリーメモリ量分の複数のＪＩＴｅｄコードを破棄する。理想的な破棄の方針は、今後使用されないＪＩＴｅｄコードを破棄することであるが、このような情報は普通得られない。類推し、しばらく呼ばれそうにない順にＪＩＴｅｄコードを破棄するのが現実的である。以下、これをＪＩＴｅｄコード破棄方針と呼ぶ。
【０００８】
通常考えられるメソッドのプロファイルに、実行頻度（何回呼ばれたか）と実行時間（プログラムカウンタがそのメソッドを指していた時間）がある。実行頻度の収集は、メソッドが呼ばれる毎にそのメソッドのカウンタを増加させて行なう。メソッドがＪＩＴコンパイラによるコンパイルされると、それまでインタプリタで測定されていた実行頻度の更新は終了し、したがってインタプリタからはＪＩＴｅｄコードに対する実行頻度情報は得られない。ＪＩＴｅｄコードで実行頻度情報を得るには、各メソッドのＪＩＴｅｄコードのプロローグで実行回数を数える必要がある。例えば、ｘ８６プラットフォームでは、inc dword ptr ［カウンタアドレス］命令を追加する。実行時間の収集は、一定時間毎に割り込み  （典型的にはタイマ割り込み、プロセッサによっては実行命令数割り込み）をかけ、プログラムカウンタ（以下、ｐｃ）を収集して行なう。
【０００９】
ＪＩＴｅｄコード破棄方針として、これら従来のプロファイルを使用すると問題が生じる。まず、実行頻度について、各メソッドのＪＩＴｅｄコード実行の度にメモリを参照してカウントするのは、メモリが枯渇しない状態へのオーバヘッドになり、問題である。さらに、頻度が少ないが直ちに呼ばれるメソッドを誤って破棄してしまう恐れがある。知りたいのは、呼ばれずにメモリを占めているＪＩＴｅｄコードであるから、目的に合わない。また実行時間についても、割り込みと収集したｐｃの管理（すぐにメソッドに対応づけるなら対応づけのコスト、対応づけないならその保存）は、メモリが枯渇しない状態へのオーバヘッドになり問題である。さらに実行頻度収集の場合と同様、実行時間が短いが直ちに呼ばれるメソッドを誤って破棄してしまう恐れがある。
【００１０】
【発明が解決しようとする課題】
上述のように、従来のプロファイル手法をＪＩＴｅｄコード破棄方針とするのは的外れで、不適切なＪＩＴｅｄコード破棄が起きる可能性がある。本発明の目的は、コード破棄するメソッドを効果的に選択するために、メソッドがすぐに実行されやすいことを表わすメソッド活動度を計算する方法を提供することである。本発明はさらに、上記方法を実行する際に使用する情報を記録するコンパイル方法及びコンパイル装置と、コンパイラを格納した記憶媒体も提供する。
【００１１】
【課題を解決するための手段】
本発明は上記課題を解決するため、コンパイル時に、メソッド中で生じ得るメソッド呼び出しに関する呼び出しマップを作成し且つ記憶装置に格納し、実際に生じたメソッド呼び出しを記録するコードを生成し且つ記憶装置に格納する。この呼び出しマップは、好適には、メソッド中のあるアドレスに対し、当該アドレス以降に生じ得るメソッド呼び出しを出力するように構成される。但し、メソッドごとにメソッド呼び出しを出力するようにしてもよい。コンパイルが終了し且つ生成されたコードが実行されると、メソッド中で生じ得るメソッド呼び出しに関する呼び出しマップと実際に生じたメソッド呼び出しに関する情報とが各メソッドごとに記録されるようになる。
【００１２】
このような状態において、コードを回収する際には、全スレッドを一時停止し、あるメソッドが実行される可能性の高低を表す活動度を計算する。この時、スタックフレームに対応する第１メソッドについての、呼び出しマップと実際に生じたメソッド呼び出しに関する情報とを用いて、第１メソッドから呼ばれる可能性が高い第２メソッドを特定し且つ記憶装置に格納し、第１メソッドに対応するスタックフレームのスタックの最上部からの段数に応じた優先度を第２メソッドの活動度に作用することにより第２メソッドの活動度を更新する。好適には、このような処理を繰り返す。すなわち、第２メソッドについての、呼び出しマップと実際に生じたメソッド呼び出しに関する情報と用いて、第２メソッドから呼ばれる可能性が高い第３メソッドを特定し且つ記憶装置に格納し、第１メソッドに対応するスタックフレームのスタックの最上部からの段数に応じた優先度を第３メソッドの活動度に作用することにより第３メソッドの活動度を更新する。このようにして求められたメソッドの活動度が低いもののコードを破棄するとより効率的なコード破棄が行える。
【００１３】
なお、好適には、呼び出しマップは、メソッド中のあるアドレスに対し、当該アドレス以降に生じ得るメソッド呼び出しを出力し、第２メソッドの特定は、第１メソッドの実行再開アドレス以降に生じ得るメソッド呼び出しを用いて行われる。
【００１４】
本発明では、非アクティブメソッドについて、現在のコンテキスト、プログラムの構造、実行時情報を利用して、すぐに呼ばれる度合い（活動度）を求める。ここでいう、現在のコンテキストの利用とは、スタック上位（トップに近い）にあるメソッドほど早く実行されそうだと判断できることである。プログラムの構造の利用とは、コントロールフロー上、一時停止しているメソッドから今後呼ばれそうなメソッドを知ることである。実行時情報の利用とは、前記呼ばれそうなメソッドでも（インタプリタを含めた）実行時に一度も呼ばれていなければ、判断対象から除外できるということである。早く呼ばれそうなメソッドの活動度が、その呼ばれる早さに応じて上げられる。
【００１５】
このように活動度は、メソッドの再実行時刻が早いほど、その値が大きい。これは、上述したＪＩＴｅｄコード破棄方針をよく模倣する点で優れている。先ほどの例でいえば、仮にＡがスタック上位、Ｂがスタック下位からそれぞれ呼ばれるメソッドであれば、本発明のアルゴリズムによってＡの活動度はＢの活動度より高くなり、Ｂより先にＡを選んで破棄することはなくなる。
【００１６】
あるスレッドでＪＩＴコンパイラのメモリ要求が満たせなくなったとき、そのメソッドは自分以外のスレッドをすべて一時停止し、アクティブメソッドを見つける。本発明によるメソッド活動度計算方法により、各メソッドの活動度を決定する。その後、このような活動度に基づいて、非アクティブなメソッドの一部あるいは全部のＪＩＴｅｄコードを破棄する。一時停止したスレッドをすべて再開し、メモリ要求を再度行なう。これをメモリ要求が満たされるまで行なう。最終的にメモリ要求が満たされない場合、許されるなら、コンパイラの最適化レベルを下げて再度コンパイルに挑戦する。再度のコンパイルが許されない場合、あるいは最低の最適化レベルでもコンパイルできなかった場合は、このメソッドをコンパイルしない。
【００１７】
メソッド活動度を計算するための作業コストを低減するために、メソッドの活動度を、これらがさらに呼び出すメソッドの活動度に作用させる動作の回数に上限を設けてもよい。
【００１８】
【発明の実施の形態】
本発明は、ＪＩＴｅｄコード破棄方針を模倣するために、メソッドに活動度と呼ばれる優先順位を与える方法である。ＪＩＴｅｄコード破棄方針とは、「しばらく呼ばれそうにない順にＪＩＴｅｄコードを破棄する」ことである。低い活動度のメソッドほど、しばらく呼ばれないと予想できる。しばらく呼ばれないメソッドのＪＩＴｅｄコードを破棄すれば、それらによって使われていたメモリ量のフリーメモリは長い間活用できるはずである。
【００１９】
以下、メソッドｍの活動度Ａ（ｍ）の計算手順を示す。各メソッドの活動度の初期値を０とする。まず、ＪＩＴコンパイラによるコンパイルおよび実行時における動作を、図２のフローチャートを参照して説明する。ステップＳ２０１で開始し、ステップＳ２０２で、メソッドｍに関して、ＪＩＴｅｄコード中のアドレスａｄｄｒと、このアドレスからメソッドの実行が再開したときに呼ばれる（あるいは可能性がある）メソッド集合とを対応させるための、アドレス−呼び出しマップＭＡＰＡ−Ｉ（ｍ）を作る。アドレス−呼び出しマップは、ａｄｄｒを含む基本ブロックＢＢ（ｂａｓｉｃ  ｂｌｏｃｋ）と、このＢＢからコントロールフロー上で到達する前記メソッド呼び出しとを対応づけるものである。このアドレス−呼び出しマップは、あるアドレスａｄｄｒが与えられたときに、このａｄｄｒから到達する全メソッド呼び出しを返す。この全メソッド呼び出しを呼び出し集合ＳＥＴＡ−Ｉ（ｍ，ａｄｄｒ）と呼ぶ。
【００２０】
アドレス−呼び出しマップの計算をするためには、コントロールフローを解析し、基本ブロックＢＢ毎に、ＢＢが到達する可能性のあるメソッド呼び出しのアドレスを集める。それから、ＢＢの先頭アドレスi ＿addrとリーチされるメソッド呼び出しアドレスi ＿callの関係データ（例えば、（i ＿addr, i ＿call）をソートした表）をコンパイルコードにつける。呼び出し集合は、ａｄｄｒを含むＢＢに対応するすべてのi ＿callである。図３は、メソッドＥのＪＩＴｅｄコードを示す線図である。メソッドＥは、ＢＢ１ないしＢＢ５から成る。この図において、アドレス１１５において、メソッドＦを呼び出している。したがって、呼び出し集合は、ａｄｄｒ＝１００〜１１５はＦを返し、ａｄｄｒ＝１１６〜１２０は何も返さない。
【００２１】
アドレス−呼び出しマップの計算コストを大幅に削減するには、正確でないが、メソッドｍのアドレス−呼び出しマップを、ｍに含まれるすべてのメソッド呼び出しの集合としてもよい。このとき呼び出し集合もｍに含まれるすべてのメソッド呼び出しの集合である。
【００２２】
ＪＩＴｅｄコード中にあるメソッド呼び出しのためのｃａｌｌ命令は、最適化のために、なるべくダイレクトコール（direct call ）になるように処理される。例えば、あるメソッド呼び出しをコンパイルする際に呼び出し先のメソッドがまだコンパイルされていない場合、コンパイラはダイレクトコール命令を生成できない。このようなメソッド呼び出しが発生すると、バックパッチコードにジャンプして、ＪＩＴコンパイラによって生成されたターゲットアドレスを次回のメソッド呼び出しから用いることができるように設定する。このような処理は従来から行われてきた。本発明では、メソッド呼び出しを最初に行う場合には、ターゲットアドレスがまだ生成されていない場合でも生成されている場合でも必ず、バックパッチコードにジャンプし、ターゲットアドレスを記録するようにする  （Ｓ２０３のコードを用いる）。２回目以降のメソッド呼び出しでは、バックパッチコードにジャンプする必要はない。
【００２３】
ステップＳ２０３で、メソッド呼び出しのバックパッチコード中に、各呼び出しコードによって実際に呼び出しが起きたことを記録するコードを生成する。この記録を有効呼び出し集合ＳＥＴＥＩ（ｍ）と呼ぶ。この有効呼び出し集合は、呼び出しアドレスとターゲットアドレスのペア（ei＿call,ei ＿target）の集合である。ei＿targetの初期値はＮＵＬＬである。ei＿targetがＮＵＬＬでない要素が意味のある要素である。
【００２４】
ステップＳ２０４で、コンパイラは、メソッドをコンパイルする際に、全てのターゲットアドレスについての表（ei＿call，ei＿target）を作り、コンパイルコードに付ける。例えば、表１のようなものである。
【表１】
0003807860.tif 000002
この表が有効呼び出し集合となる。コンパイル時の処理は以上である。
【００２５】
ＪＩＴｅｄコードが実行され、Ｓ２０３で生成されたコードが実行されると、呼び出しを行なったメソッドの有効呼び出し集合の対応するエントリ（ei＿call，ei＿target）のei＿targetが更新される。ここで、有効呼び出し集合においてei＿targetに実際のターゲットアドレスが入っている呼び出しのみが、実際に呼び出しを行なう有効呼び出しである。ステップＳ２０６で処理を終了する。なお、表１は、例えば表２のようになる。
【表２】
0003807860.tif 000003
【００２６】
次に、ＪＩＴｅｄコードの回収プロセス中（全スレッドは一時停止状態）にメソッドの活動度を決定する。以下、図４のフローチャートを参照して説明する。
【００２７】
ステップＳ４０１でコンパイル中にメモリの制限に達すると、ステップ４０２でＪＩＴコンパイラは動作中のスレッドを一時停止する。
【００２８】
ステップＳ４０３で、各スレッドにおいて、ＪＩＴｅｄコードのフレームをスタック天井から底へ向けて検索する。見つかったＪＩＴｅｄコードに対応するメソッドをアクティブメソッドｍ０と呼ぶ。
【００２９】
ステップＳ４０４で、アクティブメソッドｍ０に優先度付けする。最も天井に近いメソッドから底へ向けてｉ番め（ｉ＞＝０）のメソッドの優先度をｗ（ｉ）とする。ここで、ｗ（ｉ）＞ｗ（ｉ＋１）とする。例えば、ｗ（ｉ）＝０．９ｉとする。
【００３０】
ステップＳ４０５で、各アクティブメソッドｍ０に対して、その停止アドレスａｄｄｒ（まさにそのメソッドで一時停止されたならそのコンテキストのプログラムカウンタの値（ｐｃ）、それ以外ならフレームに保存された次のｐｃ）を用いて、アドレス−呼び出しマップＭＡＰA-I （ｍ0 ）を引いて、呼び出し集合ＳＥＴA-I （ｍ0 ，ａｄｄｒ）を得る。
【００３１】
ステップＳ４０６で、さらにメソッドｍ０の有効呼び出し集合ＳＥＴEI（ｍ0 ）を参照して、ステップＳ４０７で、ＳＥＴA-EI（ｍ0 ，ａｄｄｒ）を得る。ＳＥＴA-EI（ｍ0 ，ａｄｄｒ）は、ｍ0 のａｄｄｒから実行が再開したときに、ｍ0 から実際に実行される可能性があるメソッド呼び出しと、このメソッド呼び出しによって呼ばれるターゲットメソッドｍ1 のアドレスの集合である。ＳＥＴA-EIはメモリに格納される。
【００３２】
Ｓ４０８で、ＳＥＴA-EI（ｍ0 ，ａｄｄｒ）に含まれるすべてのターゲットメソッドｍ1 に対して、ｍ0 の優先度ｗ（ｉ）を活動度Ａ（ｍ1 ）に作用（例：加算）させる。これをＵｐｄａｔｅＡ（ｍ1 ，ｗ（ｉ））と書く。
【００３３】
同様に、ｍ1 が呼ばれたとき、ｍ1 が呼ぶ可能性の高いターゲットメソッドｍ２の集合を有効呼び出し集合ＳＥＴＥＩ（ｍ1 ）で与える。そしてさらに、ＳＥＴＥＩ（ｍ1 ）に属するすべてのターゲットメソッドｍ2 に対しても、ＵｐｄａｔｅＡ（ｍ2 、ｗ（ｉ））を行なう。以下同様にして、以降のターゲットメソッドに対して、ＵｐｄａｔｅＡ（ｍ，ｗ（ｉ））を、全メソッドに対して行われるまで繰り返す。すなわち、Ｓ４０８の後に全メソッドに対してＵｐｄａｔｅＡ（ｍ，ｗ（ｉ））を行なうまで、または所定数繰り返すまで、Ｓ４０５乃至Ｓ４０８を繰り返す。
【００３４】
図５は、ターゲットメソッドへの活動度の割り当てを説明する線図である。このスレッドのスタックの各アクティブメソッドｍ０には、スタック天井から下向きに順番に、１、０．９、０．８１の優先度ｗが割り当てられている。これらのアクティブメソッドが直接呼び出すメソッドｍ１の活動度には、ｍ０の優先度ｗが反映されている。さらに、ｍ１が呼び出すｍ２の活動度には、ｍ１の活動度  （優先度）が反映されている。但し、２以上のメソッドから活動度が伝播されてくる場合には、図５に示すように、保持している値と比較して、大きな値の方を保持するようにすることも可能である。また、図５の右にメソッドをたどるごとに活動度を低くすることも考えられる。さらに、ＵｐｄａｔｅＡ（ｍ，ｗ（ｉ））でなく、ＵｐｄａｔｅＡ（ｍx ，ｍx-1 ）のような更新処理を定義することも可能である。
【００３５】
以上で、全メソッドに活動度が割り振られた。ＪＩＴコンパイラは、メソッド活動度の低いものから順に、ＪＩＴｅｄコードを破棄し、スレッド実行を再開して、コンパイルを継続する。
【００３６】
この作業コストが問題になる場合、各スレッドにおける優先度の更新回数（ＵｐｄａｔｅＡ（ｍ，ｗ（ｉ））の実行回数）の上限を設けてもよい。
【００３７】
また、シンクロナイズド（synchronized）メソッドでブロックしているスレッドについて、あるいは低い優先度のスレッドについて、９においてスレッド実行が再開してもしばらくはディスパッチされないと考え、活動度の収集を行わなくてもよい。
【００３８】
以上本発明の処理の流れを説明したが、本発明はこれらの処理を実施する装置や、コンピュータにこれらの処理を実施させるプログラムの形態によっても実現可能である。このプログラムを、フロッピー・ディスクやＣＤ−ＲＯＭ等の記憶媒体又は他の形態の記憶装置に格納することは、通常当業者が行う事項である。
【００３９】
ここで本発明に関連する装置構成の一例を図６を用いて説明しておく。サーバ・コンピュータ１及びクライアント・コンピュータ５はネットワーク３を介して接続されている。クライアント・コンピュータ５は、ＪａｖａＶＭ（Virtual Machine ）５２及びＯＳ（Operating System）５３及びハードウエア（ＣＰＵ及びメモリを含む）５５を含む。さらに、ＪａｖａＶＭ５２は、Ｊａｖａインタープリタ５４及びＪａｖａ  ＪＩＴコンパイラ５６を含む。ＪａｖａＶＭ５２は、図示しないガベージコレクタやスタックトレーサをさらに含む。なお、クライアント・コンピュータ５は、通常のコンピュータの他、メモリの大きさが小さかったり、ハードディスク等の補助記憶装置を含まないような、いわゆるネットワーク・コンピュータや情報家電の場合もある。
【００４０】
サーバ・コンピュータ１では、Ｊａｖａソースコード１０は、Ｊａｖａコンパイラ１２によりコンパイルされる。このコンパイルの結果が、バイトコード１４である。このバイトコード１４は、ネットワーク３を介してクライアント・コンピュータ５に送信される。バイトコード１４は、クライアント・コンピュータ５内のＷＷＷブラウザ（World Wide Web Browser）などに設けられたＪａｖａ仮想マシン（Java VM ）５２にとってネイティブ・コードであり、実際ハードウエア５５のＣＰＵにて実行する場合には、Ｊａｖａインタープリタ５４や、ＪａｖａＪＩＴコンパイラ５６を用いる。インタープリタ５４は、実行時にバイトコード１４をデコードし、命令ごとに用意される処理ルーチンを呼び出して実行する。一方、ＪＩＴコンパイラ５６は、バイトコードを事前にあるいは実行する直前にコンパイラを用いてマシン・コード５８に変換してそれをＣＰＵで実行する。
【００４１】
【発明の効果】
本発明によれば、コード破棄するメソッドを効果的に選択することができるため、同一メソッドの再コンパイル回数が減少し、コンパイルオーバヘッドを減少させることができる。
【図面の簡単な説明】
【図１】  サブルーチンＡがサブルーチンＢを、サブルーチンＢがサブルーチンＣを呼び出したときのスタックを示す線図である。
【図２】  本発明によるメソッド活動度計算方法のＪＩＴコンパイルおよび実行時における動作を説明するフローチャートである。
【図３】  メソッドＥのＪＩＴｅｄコードを示す線図である
【図４】  本発明によるメソッド活動度計算方法のＪＩＴｅｄコードの回収プロセス中における動作を説明するフローチャートである。
【図５】  ターゲットメソッドへの活動度の割り当てを説明する線図である。
【図６】  本発明における装置構成の一例を示す図である。
【符号の説明】
１  サーバ・コンピュータ
３  ネットワーク
５  クライアント・コンピュータ
１０  Ｊａｖａソースコード
１２  Ｊａｖａコンパイラ
１４  バイトコード
５２  ＪａｖａＶＭ
５４  Ｊａｖａインタプリタ
５６  Ｊａｖａ  ＪＩＴコンパイラ
５８  マシンコード
６０  ガベージ・コレクタ
５３  ＯＳ
５５  ハードウエア（ＣＰＵ及びメモリを含む）
【図１】
0003807860.tif 000004
【図２】
0003807860.tif 000005
【図３】
0003807860.tif 000006
【図４】
0003807860.tif 000007
【図５】
0003807860.tif 000008
【図６】
0003807860.tif 000009