(57)【特許請求の範囲】
【請求項１】
世代別ガベージ・コレクション（ＧＣ）をサポートするコンピュータ・システムの処理により、スタック・スキャンのコストを削減する方法であって、 
スレッドごと、そのスタック内を指すスキャン不要領域開始ポインタを用意するステップと、
第１世代の(nursery)ヒープ領域のＧＣにおいて、スタックの底から前記スキャン不要領域開始ポインタが指すアドレスまでの領域が、前記第１世代のヒープ領域に存在するnurseryオブジェクトへの参照が一つも存在しない領域となるように、各スレッドの前記スキャン不要領域開始ポインタに値を設定するステップと、 
次回の第１世代のヒープ領域のＧＣにおいて、各スレッドのスタックのスキャンを、前記スキャン不要領域開始ポインタが指すスタックフレームより上のスタックフレームに対してのみ実行するステップと
を含む、スタック・スキャンのコストを削減する方法。
【請求項２】
第１世代のヒープ領域のＧＣにおいて、前記nurseryオブジェクトを参照する又は参照しうる各スタック内の１以上のアドレスを、スレッドごとに用意するnurseryオブジェクト参照リストに登録するステップ、及び、前記スキャン不要領域開始ポインタを、前記nurseryオブジェクト参照リストにリストされたアドレスが前記スタックの底から前記スキャン不要領域開始ポインタが指すアドレスまでの領域内に含まれるように更新するステップを更に含み、次回の第１世代のヒープ領域のＧＣでは、前記スタックの底から前記スキャン不要領域開始ポインタが指すアドレスまでの領域については、前記nurseryオブジェクト参照リストに含まれるアドレスに対してＧＣ処理を行うのみとする、請求項１に記載のスタック・スキャンのコストを削減する方法。
【請求項３】
少なくとも一部のスタックフレームの破棄に応答して、前記スキャン不要領域開始ポインタが破棄される前記スタックフレームを指すか否かを判定し、破棄される前記スタックフレームを指すことを条件に、前記スキャン不要領域開始ポインタに新しいスタック・ポインタの値を設定する調整処理を行うステップを更に含む、請求項２に記載のスタック・スキャンのコストを削減する方法。
【請求項４】
前記スキャン不要領域開始ポインタの値の更新に応答して、更新後の前記値により指されるスタックフレームに格納されるメソッドのリターン先の情報を、前記メソッドのリターン先へ戻る前に前記調整処理が行われるように書き換えるステップを更に含む、請求項３に記載のスタック・スキャンのコストを削減する方法。
【請求項５】
前記次回の第１世代のヒープ領域のＧＣにおいて、前処理として、前記スキャン不要領域開始ポインタを、前記調整処理のためのコードを含むメソッドに対応する最初のスタックフレームまで下げるステップを更に含む、請求項３に記載のスタック・スキャンのコストを削減する方法。
【請求項６】
前記次回の第１世代のヒープ領域のＧＣにおいて、各スレッドのスタックのスキャンを行う前に、前記nurseryオブジェクト参照リストに含まれる各アドレスについて、前記スキャン不要領域開始ポインタが指すスタックフレームよりも上のスタックフレームに含まれるか否かを判定し、前記上のスタックフレームに含まれることを条件に、該アドレスを前記nurseryオブジェクト参照リストから削除するステップを更に含む、請求項３に記載のスタック・スキャンのコストを削減する方法。
【請求項７】
前記nurseryオブジェクト参照リストにリストされるアドレスに対するＧＣ処理は、各アドレスについて、該アドレスに格納される参照によりアクセスされるオブジェクトの移動に応答して、移動後の前記オブジェクトを正しく指すように前記アドレスに格納される参照を更新することを含む、請求項３に記載のスタック・スキャンのコストを削減する方法。
【請求項８】
前記nurseryオブジェクト参照リストにリストされるアドレスに対するＧＣ処理は、前記nurseryオブジェクト参照リストに含まれる各アドレスについて、 該アドレスから参照されるオブジェクトが第２世代の（tenured）ヒープ領域に移動することを条件に、該アドレスを前記nurseryオブジェクト参照リストから削除するステップを含む、請求項３に記載のスタック・スキャンのコストを削減する方法。
【請求項９】
前記スレッドごとのスタック内に配置されたオブジェクトが存在する場合に、該オブジェクト内の参照フィールドのアドレスを、対応する前記nurseryオブジェクト参照リストに追加するステップを更に含む、請求項３に記載のスタック・スキャンのコストを削減する方法。
【請求項１０】
前記スキャン不要領域開始ポインタの上限を、先頭のスタックフレームから所定数のスタックフレーム分移動した位置のアドレスに設定し、設定された前記上限より上に積まれたデータのアドレスの前記nurseryオブジェクト参照リストへの登録を禁止するステップを更に含む、請求項３に記載のスタック・スキャンのコストを削減する方法。
【請求項１１】
ガベージ・コレクション（ＧＣ）をサポートするコンピュータ・システムの処理により、スタック・スキャンのコストを削減する方法であって、
スレッドごと、その実行スタック内を指すスキャン不要領域開始ポインタと、オブジェクトを参照する又は参照しうるスタック内の１以上のアドレスを登録するオブジェクト参照リストとを用意するステップと、
ＧＣにおいて、オブジェクトを参照する又は参照しうるスタック内の１以上のアドレスを前記オブジェクト参照リストに登録し、かつ、前記スキャン不要領域開始ポインタを、スタックの底から前記スキャン不要領域開始ポインタが指すアドレスまでの領域内に前記オブジェクト参照リストにリストされたアドレスが含まれるように設定するステップと、
次回以降のＧＣにおいて、前記スタックの底から前記スキャン不要領域開始ポインタが指すアドレスまでの領域については、前記オブジェクト参照リストに含まれるアドレスに対してＧＣ処理を行うのみとする、スタック・スキャンのコストを削減する方法。
【請求項１２】
コンピュータに、請求項１乃至１１のいずれか１項に記載のスタック・スキャンのコストを削減する方法の各ステップを実行させるためのスタック・スキャンのコストを削減するためのプログラム。
【請求項１３】
請求項１乃至１１のいずれか１項に記載のスタック・スキャンのコストを削減す方法の各ステップを実行するように適合された手段を備える、スタック・スキャンのコストを削減するためのコンピュータ・システム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、コンピュータにおいてガベージ・コレクション（ＧＣ）におけるスタック・スキャンのコストを削減するための技術に関し、より詳細には、ＧＣの結果を再利用することでＧＣにおけるスタック・スキャンのコストを削減するための技術に関する。
【背景技術】
【０００２】
最近のJava(R)処理系では、ＧＣのコストがJava(R)アプリケーションの性能に大きく影響することから、世代別ＧＣを用いることでＧＣの停止時間を低減している。世代別ＧＣではヒープ領域を、新しいオブジェクトを割り付けるための第１世代の（nursery）ヒープ領域と、第１世代のヒープ領域のＧＣを複数回生き残ったオブジェクトを移動させるための第２世代の（tenure）ヒープ領域に分割する。そして、通常は第１世代のヒープ領域のＧＣだけを行い、空き領域が確保できなくなった場合に限りヒープ領域全体のＧＣを行うことで、ＧＣにかかる全体の時間の短縮を図っている。
【０００３】
上記第１世代のヒープ領域のＧＣは、当該領域に存在するオブジェクトの生死だけをチェックするため、高速に行うことができる。しかし、生きているオブジェクトを漏れなく確認するには、「ＧＣルート（root）」と呼ばれる領域のスキャンは省略することができない。ＧＣルートにはスタティック変数や各種のテーブル、第２世代のヒープ領域からの参照を示す「リメンバーセット」などがある。
【０００４】
さて、最近の大規模アプリケーションでは、スタックフレームの段数が深くなり、また、大量のスレッドが生成される傾向にある。これは、最近の大規模アプリケーションが、Java(R)上の各種フレームワーク（WAS，ICA，IOCなど）の上に構築されることが多くなり、また、Java(R) VMの上に別の言語処理系を実装する（JRuby，Jython，P8など）ことが一般的になっているためである。このため、大規模アプリケーションでは、スタック・スキャンにかかる時間が増大し、スタック・スキャンのコストが第１世代のヒープ領域のＧＣのオーバーヘッドの主要因となっている。
【０００５】
ＧＣのコスト削減に関する従来技術として、特許文献１〜３が存在する。特許文献１は、アプリケーション・プログラムが生成するオブジェクトを、１つのスレッドと対応付けられたスレッドローカルヒープに生成し、上記生成されたオブジェクトを参照することができるスレッドが変化することに応じて、適切なスレッドグループヒープに移動させ、不要になったオブジェクトを回収する際に、上記不要になったオブジェクトを参照することができるスレッドのみを停止する技術を開示する。
【０００６】
また特許文献２は、アプリケーション・プログラムの起動時に実行時ライブラリを呼び出して、そのアプリケーション・プログラムの解析を行うことによりその生成される各オブジェクトが、メソッド内部でのみ利用されるオブジェクトであるか否かをそれぞれ判定し、メソッド内部でのみ利用されるオブジェクトはスタック領域のフレーム上に生成し、それ以外のオブジェクトはヒープ領域上に生成する技術を開示する。
【０００７】
また特許文献３は、ガベージコレクション実行手段と、ガベージコレクションを実行する毎にガベージコレクションの回数とガベージコレクションを実行した後のメモリ量を記録するガベージコレクション記録手段と、ガベージコレクション記録手段の記録に基づいて、ガベージコレクションの実行によりメモリの拡張を必要とする場合の拡張メモリ量を定めるメモリチャートを求める拡張メモリ量変換手段と、拡張メモリ量変換手段の求めた拡張メモリ量を保持する拡張メモリ量保持手段と、プログラムの実行においてメモリの拡張を必要とする場合に、拡張メモリ量保持手段を参照し、メモリ拡張チャートをもとに拡張メモリ量を決定するメモリ拡張手段とを備えるメモリ管理装置を開示する。
【０００８】
特許文献１〜３は、ＧＣによる実行停止時間や回数を減らす技術を開示するが、いずれの技術も、ＧＣにおけるスタック・スキャンにかかる時間を短縮することには適用できない。
【０００９】
一方、非特許文献１は、スタックが深いプログラムについてはスタック・スキャンのコストが高くなることから、変化のないスタック領域については繰り返しスキャンを行わずに以前のＧＣの結果を再利用する技術（セクション5. Generational Stack Collectionを参照。）を開示する。
【００１０】
しかしながら、非特許文献１の技術は、第１世代のヒープ領域にあるライブオブジェクトを次回のＧＣ時に必ず第２世代のヒープ領域に移す初期の単純な世代別ＧＣを対象としているため、一度スキャンしたスタック領域に、第１世代のヒープ領域に存在するオブジェクト（以下、「nurseryオブジェクト」ともいう）への参照が残っている状況を考慮することはない。そのため、非特許文献１の技術を、第１世代のヒープ領域のＧＣを複数回生き残ったオブジェクトを第２世代のヒープ領域に移す近代の世代別ＧＣに対して、そのまま適用することはできない。
【先行技術文献】
【特許文献】
【００１１】
【特許文献１】特開第２００４−２４６７５３号公報
【特許文献２】特開２００４−７８７５０号公報
【特許文献３】特開平１１−３１２１１７号公報
【非特許文献】
【００１２】
【非特許文献１】Perry Cheng, Robert Hrper,Peter Lee, “Generational Stack Collection andProfile-Driven Pretenuring”,Proceedings of the ACM SIGPLAN 1998 conference on Programming language designand implementation, p.162-173, June 17-19, 1998, Montreal, Quebec, Canada
【発明の概要】
【発明が解決しようとする課題】
【００１３】
従って、本発明の目的は、近代的な世代別ＧＣを含むＧＣにおけるスタック・スキャンにかかる時間の短縮を図ることのできる技術を提供することにある。
【課題を解決するための手段】
【００１４】
上記課題を解決するために、本発明の１態様によれば、以下のような、世代別ＧＣをサポートするコンピュータ・システムの処理により、スタック・スキャンのコストを削減する方法が提供される。そのようなスタック・スキャンのコストを削減する方法は、スレッドごと、そのスタック内を指すスキャン不要領域開始ポインタを用意するステップと、第１世代の(nursery)ヒープ領域のＧＣにおいて、スタックの底から前記スキャン不要領域開始ポインタが指すアドレスまでの領域が、前記第１世代のヒープ領域に存在するnurseryオブジェクトへの参照が一つも存在しない領域となるように、各スレッドの前記スキャン不要領域開始ポインタに値を設定するステップと、次回の第１世代のヒープ領域のＧＣにおいて、各スレッドのスタックのスキャンを、前記スキャン不要領域開始ポインタが指すスタックフレームよりも上（言い換えると、前記スタックの先頭側）のスタックフレームに対してのみ実行するステップとを含む。
【００１５】
好ましくは、上記方法は、第１世代のヒープ領域のＧＣにおいて、前記nurseryオブジェクトを参照する又は参照しうる各スタック内の１以上のアドレスを、スレッドごとに用意するnurseryオブジェクト参照リストに登録するステップ、及び、前記スキャン不要領域開始ポインタを、前記nurseryオブジェクト参照リストにリストされたアドレスが前記スタックの底から前記スキャン不要領域開始ポインタが指すアドレスまでの領域内に含まれるように更新するステップを更に含み、次回の第１世代のヒープ領域のＧＣでは、前記スタックの底から前記スキャン不要領域開始ポインタが指すアドレスまでの領域については、前記nurseryオブジェクト参照リストに含まれるアドレスに対してＧＣ処理を行うのみとする。
【００１６】
より好ましくは、上記方法は、前記次回の第１世代のヒープ領域のＧＣにおいて、各スレッドのスタックのスキャンを行う前に、前記nurseryオブジェクト参照リストに含まれる各アドレスについて、前記スキャン不要領域開始ポインタが指すスタックフレームよりも上（言い換えると、前記スタックの先頭側）のスタックフレームに含まれるか否かを判定し、前記より上のスタックフレームに含まれることを条件に、該アドレスを前記nurseryオブジェクト参照リストから削除するステップを更に含む。  
【００１７】
前記nurseryオブジェクト参照リストにリストされるアドレスに対するＧＣ処理は、各アドレスについて、該アドレスに格納される参照によりアクセスされるオブジェクトの移動に応答して、移動後の前記オブジェクトを正しく指すように前記アドレスに格納される参照を更新することを含む。
【００１８】
より好ましくは、前記nurseryオブジェクト参照リストにリストされるアドレスに対するＧＣ処理は、前記nurseryオブジェクト参照リストに含まれる各アドレスについて、当該アドレスから参照されるオブジェクトが第２世代の（tenured）ヒープ領域に移動することを条件に、該アドレスを前記nurseryオブジェクト参照リストから削除するステップを含む。
【００１９】
また好ましくは、上記方法は、少なくとも一部のスタックフレームの破棄に応答して、前記スキャン不要領域開始ポインタが破棄される前記スタックフレームを指すか否かを判定し、破棄される前記スタックフレームを指すことを条件に、前記スタックフレームが破棄された後の新しいスタック・ポインタの値を前記スキャン不要領域開始ポインタに設定する調整処理を行うステップを更に含む。
【００２０】
より好ましくは、上記方法は、前記次回の第１世代のヒープ領域のＧＣにおいて、前処理として、前記スキャン不要領域開始ポインタを、前記調整処理を含むコードに対応する最初のスタックフレームまで下げるステップを更に含む。
【００２１】
また、より好ましくは、上記方法は、記スキャン不要領域開始ポインタの値の更新に応答して、更新後の前記値により指されるスタックフレームに格納されるメソッドのリターン先の情報を、前記メソッドのリターン先へ戻る前に前記調整処理が行われるように書き換えるステップを更に含む。
【００２２】
また好ましくは、上記方法は、前記スレッドごとのスタック内に配置されたオブジェクトが存在する場合に、該オブジェクト内の参照フィールドのアドレスを、対応する前記nurseryオブジェクト参照リストに追加するステップを更に含む。
【００２３】
また好ましくは、上記方法は、前記スキャン不要領域開始ポインタの上限を、先頭のスタックフレームから所定数のスタックフレーム分移動した位置のアドレスに設定し、設定された前記上限より上に積まれたデータのアドレスの前記nurseryオブジェクト参照リストへの登録を禁止するステップを更に含む。
【００２４】
本発明の他の態様によれば、以下のような、ＧＣをサポートするコンピュータ・システムの処理により、スタック・スキャンのコストを削減する方法が提供される。そのようなスタック・スキャンのコストを削減する方法は、スレッドごと、その実行スタック内を指すスキャン不要領域開始ポインタと、オブジェクトを参照する又は参照しうるスタック内の１以上のアドレスを登録するオブジェクト参照リストとを用意するステップと、ＧＣにおいて、オブジェクトを参照する又は参照しうるスタック内の１以上のアドレスを前記オブジェクト参照リストに登録し、かつ、前記スキャン不要領域開始ポインタを、スタックの底から前記スキャン不要領域開始ポインタが指すアドレスまでの領域内に前記オブジェクト参照リストにリストされたアドレスが含まれるように設定するステップとを含み、次回以降のＧＣにおいては、前記スタックの底から前記スキャン不要領域開始ポインタが指すアドレスまでの領域については、前記オブジェクト参照リストに含まれるアドレスに対してＧＣ処理を行うのみとする。
【００２５】
以上、スタック・スキャンのコストを削減する方法として本発明を説明したが、本発明は、上記説明したスタック・スキャンのコストを削減する方法の各ステップをコンピュータに実行させるためのスタック・スキャンのコストを削減するためのプログラムとして把握することもできる。また、そのようなスタック・スキャンのコストを削減する方法の各ステップを実行するように適合された手段を備えるスタック・スキャンのコストを削減するためのコンピュータ・システムとして把握することもできる。
【発明の効果】
【００２６】
本発明によれば、スレッドごと、そのスタック内を指すスキャン不要領域開始ポインタが用意され、ＧＣにおいて、スタックの底からスキャン不要領域開始ポインタが指すアドレスまでの領域が、ヒープ領域に存在するオブジェクトへの参照が一つも存在しえない領域となるように、各スレッドの上記スキャン不要領域開始ポインタに値が設定されるので、次回のヒープ領域のＧＣでは、各スレッドのスタックのスキャンを、スキャン不要領域開始ポインタが指すスタックフレームよりも上のスタックフレームに対してのみ実行すればよくなり、近代的な世代別ＧＣを含むＧＣにおけるスタック・スキャンにかかる時間の短縮を図ることが可能となる。
【００２７】
更に、ＧＣにおいて、オブジェクトを参照する又は参照しうる各スタック内の１以上のアドレスを、スレッドごとに用意するオブジェクト参照リストに登録し、かつ、スキャン不要領域開始ポインタを、オブジェクト参照リストにリストされたアドレスが、スタックの底からスキャン不要領域開始ポインタが指すアドレスまでの領域内に含まれるように更新することで、次回のヒープ領域のＧＣでは、スタックの底からスキャン不要領域開始ポインタが指すアドレスまでの領域については、オブジェクト参照リストに含まれるアドレスに対してＧＣ処理を行うだけでよくなり、近代的な世代別ＧＣを含むＧＣにおけるスタック・スキャンにかかる時間の更なる短縮を図ることが可能となる。本発明のその他の効果については、各実施の形態の記載から理解される。
【図面の簡単な説明】
【００２８】
【図１】本発明を実施するのに好適なコンピュータ・システムのハードウェア構成の一例を示した図である。
【図２】本発明を実施するためのソフトウェアの階層を示す図である。
【図３】スキャン不要開始ポインタが示す情報とnurseryオブジェクト参照リストに含まれる情報を説明する図である。
【図４】第１世代のヒープ領域のＧＣ処理のフローチャートの一例を示す図である。
【図５】nurseryオブジェクト参照リストを用いたＧＣ処理のフローチャートの一例を示す図である。
【図６】スタックフレームの破棄に応答して実行される処理のフローチャートの一例を示す図である。
【発明を実施するための形態】
【００２９】
以下、本発明を実施するための形態を図面に基づいて詳細に説明するが、以下の実施形態は特許請求の範囲にかかる発明を限定するものではなく、また実施形態の中で説明されている特徴の組み合わせの全てが発明の解決手段に必須であるとは限らない。なお、実施の形態の説明の全体を通じて同じ要素には同じ番号を付している。
【００３０】
図１を参照すると、本発明の一実施例に係るシステム構成及び処理を実現するためのコンピュータ・ハードウェアのブロック図が示されている。図１において、システム・バス１０２には、ＣＰＵ１０４と、主記憶（ＲＡＭ）１０６と、ハードディスク・ドライブ（ＨＤＤ）１０８と、キーボード１１０と、マウス１１２と、ディスプレイ１１４が接続されている。ＣＰＵ１０４は、好適には、３２ビットまたは６４ビットのアーキテクチャに基づくものであり、例えば、インテル社のCore(商標)i3、Core(商標) i5、Core(商標)i7、Xeon(R)、AMD社のAthlon(商標)、Phenom(商標)、Sempron(商標)などを使用することができる。主記憶１０６は、好適には、８ＧＢ以上の容量、より好ましくは、１６ＧＢ以上の容量をもつものである。
【００３１】
ハードディスク・ドライブ１０８には、オペレーティング・システム（ＯＳ）２０２（図２）が、格納されている。オペレーティング・システムは、Linux（商標）、マイクロソフト社のWindows(商標) 7、Windows8(商標)、Windows(商標)2003サーバ、アップルコンピュータのMac OS(商標)などの、ＣＰＵ１０４に適合する任意のものでよい。
【００３２】
ハードディスク・ドライブ１０８にはまた、Apacheなどの、Ｗｅｂサーバとしてシステムを動作させるためのプログラムが保存され、システムの起動時に、主記憶１０６にロードされる。
【００３３】
ハードディスク・ドライブ１０８にはさらに、Java(R)仮想マシン（ＪＶＭ）２０４（図２）を実現するためのJava(R) Runtime Environmentプログラムが保存され、システムの起動時に、主記憶１０６にロードされる。ＪＶＭ２０４には、本発明の機能が実装されている。
【００３４】
ハードディスク・ドライブ１０８にはさらに、アプリケーション・プログラムのバイトコード２０６（図２）が保存されている。
【００３５】
キーボード１１０及びマウス１１２は、オペレーティング・システムが提供するグラフィック・ユーザ・インターフェースに従い、ディスプレイ１１４に表示されたアイコン、タスクバー、テキストボックスなどのグラフィック・オブジェクトを操作するために使用される。
【００３６】
ディスプレイ１１４は、これには限定されないが、好適には、１０２４×７６８以上の解像度をもち、３２ビットtrue
colorのＬＣＤモニタである。ディスプレイ１１４は例えば、ＪＶＭ上で実行されるアプリケーション・プログラムによる動作の結果を表示するために使用される。
【００３７】
通信インターフェース１１６は、好適には、イーサネット(R)プロトコルにより、ネットワークと接続されている。通信インターフェース１１６は、クライアント・コンピュータ（図示しない）からApacheが提供する機能により、ＴＣＰ／ＩＰなどの通信プロトコルに従い、処理リクエストを受け取り、あるいは処理結果を、クライアント・コンピュータ（図示しない）に返す。
【００３８】
図２を参照すると、本発明を実施するためのソフトウェアの階層が示されている。アプリケーション・プログラム２０６は、Java(R)バイトコードから構成され、ＪＶＭ２０４上で動作する。ＪＶＭ２０４は、本発明のスタック・スキャンのコストを削減するための機能をＧＣの機能の一部として備えた、カスタマイズされたＪＶＭである。ＪＶＭ２０４はまた、JITコンパイラを含んでよい。
【００３９】
ＪＶＭ２０４は、アプリケーション・プログラム２０６のために、主記憶１０６上にヒープ領域を用意する。アプリケーション・プログラム２０８は、動作中にヒープ領域上にメモリ領域を獲得して、そこに、生成したオブジェクトを割り付ける。
【００４０】
ＪＶＭ２０４は、好ましくは、世代別ヒープ領域をサポートする。世代別ヒープ領域は、新しいオブジェクトを割り付けるための、少なくとも１つの第１世代の(nursery)ヒープ領域と、少なくとも１つの第２世代の(tenured)ヒープ領域からなり、ＪＶＭ２０４は、第１世代のヒープ領域にオブジェクトが割り当てられなくなったとき、第１世代のヒープ領域に対するＧＣを行い、第１世代のヒープ領域のＧＣを複数回生き残ったオブジェクトを第１世代のヒープ領域から、第２世代のヒープ領域に移動する。結果的に、第２世代のヒープ領域には、しばらく生き残っているオブジェクトが集まる。また、第２世代のヒープ領域が一杯になると、ＪＶＭ２０４はヒープ領域全体のＧＣを行う。
【００４１】
ＪＶＭ２０４は、非世代別ヒープ領域をサポートするものであってもよい。一方、非世代別ヒープ領域である場合、ヒープ領域は全て、第２世代のヒープ領域として扱われる。本発明は、世代別ヒープ領域と非世代別ヒープ領域の両方に適用可能である。以下では、ＪＶＭ２０４は、世代別ＧＣをサポートするものとして説明する。なお、非世代別ＧＣをサポートするＪＶＭ２０４に対しては、ヒープ領域全体のＧＣに対して本発明を適用すればよく、世代別ＧＣと非世代別ＧＣとの間で適用の仕方に違いはない。
【００４２】
上述したように最近のJava(R)アプリケーションは、スレッドのスタックが深くなる傾向にある。しかしながら、スタックの下の方には各種フレームワークや言語処理系の初期化コードのフレームが積みあげられているため、実際の処理は専らスタックの上の方だけで行われ、下の方は全く変更されないことが多い。そこで本発明ではこの性質を利用して、スタックの変更されていない部分については前回のＧＣにおけるスキャン結果を利用し、スキャン処理のコストを下げる。なお、本明細書において、スタックのエントリは下から上（ボトムアップ）に格納するものとする。もちろん本発明は、スタックのエントリを上から下（トップダウン）に格納する場合や、エントリが複数のメモリ領域に分かれている場合にも適用可能である。
【００４３】
スキャン結果の再利用で重要になるのは、スタックの変更されていない部分に存在する、第１世代のヒープ領域に存在するnurseryオブジェクトへの参照の扱いである。近代の世代別ＧＣでは、第１世代のヒープ領域に存在するオブジェクトはＧＣを複数回生き残った後第２世代のヒープ領域に移される。そのため、スキャンしたスタック領域にnurseryオブジェクトへの参照がある場合は、第２世代のヒープ領域へ移されるまでそのnurseryオブジェクトを監視する必要がある。
【００４４】
そこでＪＶＭ２０４は、管理するスレッドごとにスキャン不要領域開始ポインタと、nurseryオブジェクト参照リストとを新たに導入する。ここで、スレッドごとのスキャン不要領域開始ポインタは、そのスレッドに割り当てられたスタック内を指すものであり、第１世代のヒープ領域のＧＣにおいて従来のスタック・スキャンを必要としない領域を示すためのものである。また、スレッドごとのnurseryオブジェクト参照リストは、そのスレッドに割り当てられたスタックについて、nurseryオブジェクトへの参照を格納するアドレスをリストするものである。
【００４５】
ＪＶＭ２０４は、第１世代のヒープ領域のＧＣにおいてスタック・スキャンを行う際に、スタックの底からスキャン不要領域開始ポインタが指すアドレスまでの領域が、nurseryオブジェクトへの参照が一つも存在しない領域となるように、各スレッドのスキャン不要領域開始ポインタに値を設定する。そして、ＪＶＭ２０４は、次回の第１世代のヒープ領域のＧＣにおいて、各スレッドのスタックのスキャンを、スキャン不要領域開始ポインタが指すスタックフレームより上のスタックフレームに対してのみ実行する。
【００４６】
上記に代えて、又は、上記に加えて、ＪＶＭ２０４は、第１世代のヒープ領域のＧＣにおいてスタック・スキャンを行う際に、nurseryオブジェクトを参照する又は参照しうるスタックのアドレスをnurseryオブジェクト参照リストに登録してもよい。また、ＪＶＭ２０４は、スキャン不要領域開始ポインタを、nurseryオブジェクト参照リストにリストされたアドレスがスタックの底からスキャン不要領域開始ポインタが指すアドレスまでの領域内に含まれるように更新してよい。そして、ＪＶＭ２０４は、次回の第１世代のヒープ領域のＧＣにおいて、スタックの底からスキャン不要領域開始ポインタが指すアドレスまでの領域については、スタック・スキャンを行うことなく、nurseryオブジェクト参照リストに含まれるアドレスに対してＧＣ処理を行ってよい。
【００４７】
図３を参照すると、上記他の実施例におけるスキャン不要領域開始ポインタ３１６と、nurseryオブジェクト参照リスト３１８とが、スレッドのスタック３００と共に示されている。スタックのエントリはボトムアップに格納されており、第１世代のヒープ領域のＧＣ処理時のスタック・ポインタ３１４は、一番上のスタックフレームを指している。
【００４８】
nurseryオブジェクト参照リスト３１８には、前回の第１世代のヒープ領域のＧＣにおいて見つけられた、nurseryオブジェクトへの参照が格納されたスタック領域３０６、３０８それぞれのアドレスがリストされている。そして、スキャン不要領域開始ポインタ３１６には、nurseryオブジェクト参照リストにリストされたアドレスがスタックの底からスキャン不要領域開始ポインタが指すアドレスまでの領域内に含まれるように値が設定されている。より具体的には、そのようなスキャン不要領域開始ポインタ３１６の値として、前回のＧＣ処理以降のスタック・ポインタの下限値（つまり、それより下のスタックフレームは変更されていない）が設定されている。
【００４９】
第１世代のヒープ領域のＧＣ処理時には、ＪＶＭ２０４は、スキャン不要領域開始ポインタが指すスタックフレームより上のスタックフレームの領域３１０に対してのみスタック・スキャンを実行する。スタックの底からスキャン不要領域開始ポインタ３１６が指すアドレスまでの領域３１２については、ＪＶＭ２０４はスキャンを行わず、nurseryオブジェクト参照リストに含まれるアドレスに対してＧＣ処理のみを行う。結果、近代的な世代別ＧＣを含むＧＣにおけるスタック・スキャンにかかる時間の更なる短縮が図られる。
【００５０】
以下、新たに導入するスレッドごとのスキャン不要領域開始ポインタと、nurseryオブジェクト参照リストの管理方法及び利用方法について、当初よりnurseryオブジェクト参照リストを用いる例に従い詳細に説明する。
【００５１】
1. スレッド生成時の追加処理
1.1 スキャン不要領域開始ポインタには、該スレッドに割り当てられたスタックの底を設定する。
1.2 nurseryオブジェクト参照リストとして空のリストを生成する。
【００５２】
2. スレッド消滅時の追加処理
スキャン不要領域開始ポインタ及びnurseryオブジェクト参照リストを破棄する。
【００５３】
3. スタックフレーム作成時（メソッドの入り口）の追加処理
なし
【００５４】
4. スタックフレーム破棄時（メソッドの出口）の追加処理
スキャン不要領域開始ポインタが破棄されるスタックフレームを指すか否かを判定し、破棄されるスタックフレームを指すことを条件に、スキャン不要領域開始ポインタに新しいスタック・ポインタの値を設定する調整処理を行うように全てのメソッドの出口のコードを書き換える。スキャン不要領域開始ポインタが、破棄されるスタックフレームを指すか否かの判定に代えて、新しいスタック・ポインタが、スキャン不要領域開始ポインタよりも下である否かの判定を実行するようにしてもよい。そして新しいスタック・ポインタが、スキャン不要領域開始ポインタよりも下であることを条件に、スキャン不要領域開始ポインタに新しいスタック・ポインタの値を設定する調整処理を行うようにしてもよい。
【００５５】
5. 第１世代のヒープ領域のＧＣにおける処理
5.1 例えば、スタティック変数や各種のテーブル等、スタック以外のＧＣルートのスキャンは従来と同様に行う。
5.2 各スレッドのnurseryオブジェクト参照リストにリストされている各アドレスについて、以下の処理を行う。
5.2.1 各スレッドのスタックのスキャンを行う前に、各アドレスについて、該アドレスが、対応するスキャン不要領域開始ポインタが指すスタックフレームよりも上のスタックフレームに含まれるか否かを判定し、上記アドレスが、対応するスキャン不要領域開始ポインタが指すスタックフレームよりも上のスタックフレームに含まれることを条件に、上記アドレスをnurseryオブジェクト参照リストから削除する。なお、削除したアドレスのスタック領域は、変更されている可能性があるため、後で通常のスキャンを行う。
5.2.2各アドレスについて、該アドレスから参照されるオブジェクト、言い換えると、該アドレスに格納される参照によりアクセスされるオブジェクト、に対してＧＣ処理を行う。オブジェクトは、第１世代のヒープ領域の新しい領域か、又は、第２世代のヒープ領域に移されるので、移動後のオブジェクトを正しく指すように上記アドレスに格納されている参照を更新する。なお、当該処理以前にオブジェクトが移動済みの場合は、参照の更新のみ行う。
5.2.3各スレッドのスタックのスキャンの後、対応するnurseryオブジェクト参照リストに含まれる各アドレスについて、該アドレスに格納される参照によりアクセスされるオブジェクトが第２世代のヒープ領域に移動するなどによって当該アドレスから上記nurseryオブジェクトを参照する可能性がなくなることを条件に、該アドレスをnurseryオブジェクト参照リストから削除する。
5.3 各スレッドのスキャン不要領域開始ポインタが指すスタックフレームより上のスタックフレームに対して、従来と同様にスキャンしＧＣ処理を行う。この際、nurseryオブジェクトを参照する又は参照しうる各スタック内のアドレスを全て、対応するnurseryオブジェクト参照リストに登録する。なお、nurseryオブジェクトを参照しうるスタック内のアドレスの詳細については、7.の拡張Ａで後述する。
5.4 各スレッドのスキャン不要領域開始ポインタを、対応するnurseryオブジェクト参照リストにリストされたアドレスがスタックの底からスキャン不要領域開始ポインタが指すアドレスまでの領域内に含まれるように更新する。
【００５６】
6. 第２世代のヒープ領域のＧＣにおける処理
従来通りの処理をする。
【００５７】
7. 拡張
上述した実施例に対し、様々な拡張が考えられる。
【００５８】
オブジェクトをスタック内に配置する場合、そのオブジェクト内の参照フィールドは、より上のスタックフレームを実行中でも書き換えられることがある。この問題は、スタック内に配置したオブジェクト内の参照フィールドのアドレスは常にnurseryオブジェクト参照リストに登録することで対応できる（拡張Ａ）。なお、スタックフレーム内にどのような種類のデータが保持されるか、ＪＶＭ２０４は、メソッドの情報から判断できる。そのため、スタック内に配置したオブジェクト内の参照フィールドのアドレスに限定されず、ＪＶＭ２０４は、nurseryオブジェクトを現在参照していなくても書き換えにより将来参照する可能性の有る全てのスタック内のアドレスを、nurseryオブジェクト参照リストに登録してよい。
【００５９】
スタックの上の方のスタックフレームは頻繁に変更されると考えられる。そこで、スキャン不要領域開始ポインタに上限を設け、第１世代のヒープ領域のＧＣにおいて、スキャン不要領域開始ポインタの更新は、上限を超えない範囲で行うものとする（拡張Ｂ）。ここで、スキャン不要領域開始ポインタの上限には、先頭のスタックフレームから所定数のスタックフレーム分下に移動した位置を設定するのが好ましい。当然ながら、設定された上限より上に積まれたデータのアドレスがnurseryオブジェクト参照リストに含まれる場合、そのアドレスは削除する。若しくはそのようなデータのアドレスのnurseryオブジェクト参照リストへの追加を禁止する。これによりリストのサイズを小さくすることが可能となる。
【００６０】
4.で上述したように、スタックフレームが破棄される際、スキャン不要領域開始ポインタの値はチェックされ必要に応じて更新される。全てのメソッドの出口においてかかる処理を行うとなるとオーバーヘッドとなるため、一部のメソッドの出口でのみ4.で説明した調整処理を行うものとする。この場合、スキャン不要領域開始ポインタがスタック内の不適切な位置を指すことも起こりえる。そこで第１世代のヒープ領域のＧＣにおいて、前処理として、スキャン不要領域開始ポインタを、上述した調整処理のためのコードを含むメソッドに対応する最初のスタックフレームまで下げる（拡張Ｃ）。
【００６１】
上記処理に代えて、5.4で上述したスキャン不要領域開始ポインタの値の更新に応答して、更新後の値により指されるスタックフレームに格納されるメソッドのリターン先の情報を、メソッドのリターン先へ戻る前に4.で上述した調整処理が行われるように書き換えてもよい（拡張Ｄ）。すなわち、各スタックフレームのメソッドのリターンアドレスは、本来はその呼び出し元を指しているが、5.4で上述したスキャン不要領域開始ポインタを更新する（上げる）処理の際に、更新前の元の位置から更新後の新しい位置までの間にある各スタックフレームのメソッドのリターンアドレスを修正し、4.で説明した調整処理を行うようにする。この修正後のアドレスは、調整処理を行ってから本来のリターン先に飛ぶ処理を行うコードを指し、該コードは、ＪＶＭ２０４が内部的にランタイムとして用意しておくことで実装してよい。なお、本来の呼び出し元を指すアドレスは、書き換え時にスタックフレームごとに用意した場所に格納して退避させる。かかる構成によれば、スキャン不要領域開始ポインタの値のチェックは必要最低限に抑えることが可能となる。
【００６２】
次に図４〜図６を参照して、本発明のスタック・スキャンのコストを削減するための処理の流れを説明する。図４は、第１世代のヒープ領域のＧＣ処理のフローチャートの一例を示す図である。図５は、nurseryオブジェクト参照リストを用いたＧＣ処理のフローチャートの一例を示す図である。図６は、スタックフレームの破棄に応答して実行される処理のフローチャートの一例を示す図である。
【００６３】
図４に示す第１世代のヒープ領域のＧＣ処理は、ステップ４００で開始し、ＪＶＭ２０４は、スタックを除くＧＣルートのスキャンを行う。続いて、ＪＶＭ２０４は、スキャン不要領域開始ポインタの修正処理を行う（ステップ４０２）。即ち、ＪＶＭ２０４は、スキャン不要領域開始ポインタを、4.で説明した調整処理のためのコードを含むメソッドに対応する最初のスタックフレームまで下げる。但しステップ４０２の処理はオプションである。
【００６４】
続いてＪＶＭ２０４は、nurseryオブジェクト参照リストを用いてＧＣ処理を行う（ステップ４０４）。ステップ４０４の処理の詳細は図５を参照して後述する。続いてＪＶＭ２０４は、スキャン不要領域開始ポインタが指すスタックフレームよりも上のスタックフレームのスキャンを実行する（ステップ４０６）。
【００６５】
続いてＪＶＭ２０４は、ステップ４０６におけるスキャンの結果、nurseryオブジェクトへの参照を格納するスタックのアドレスが見つかれば、これをnurseryオブジェクト参照リストに追加する（ステップ４０８）。ＪＶＭ２０４はまた、スキャン不要領域開始ポインタを更新して、スタックの底からスキャン不要領域開始ポインタが指すアドレスまでの領域に、nurseryオブジェクト参照リストにリストされたアドレスが全て含まれるようにする（ステップ４０８）。
【００６６】
続いてＪＶＭ２０４は、スキャン不要領域開始ポインタの値を更新したことに応答して、更新後のスキャン不要領域開始ポインタが指すスタックフレームに対応するメソッドについて、そのリターン位置において4.で上述した調整処理が行われるように、コード、より詳細には、上記スタックフレームに格納されたメソッドのリターン先の情報を書き換える（ステップ４１０）。更なる詳細は、拡張Ｄの説明の繰り返しになるため省略する。なお、ステップ４１０の処理はオプションである。そして処理は終了する。
【００６７】
図５に示すnurseryオブジェクト参照リストを用いたＧＣ処理は、ステップ５００で開始し、ＪＶＭ２０４は、nurseryオブジェクト参照リストをチェックし、スキャン不要領域開始ポインタが指すスタックフレームよりも上のスタックフレームに含まれるアドレスを削除する。
【００６８】
続いてＪＶＭ２０４は、nurseryオブジェクト参照リストから順にアドレスを読み出し、該アドレスのスタック領域に格納される参照によってアクセスされるnurseryオブジェクトについてＧＣ処理を行う（ステップ５０２）。
【００６９】
続いてＪＶＭ２０４は、nurseryオブジェクト参照リストに含まれる各アドレスについて、該アドレスから参照されるnurseryオブジェクトがステップ５０２の処理の結果、第２世代のヒープ領域に移動するなどによって当該アドレスから前記nurseryオブジェクトを参照する可能性がなくなることを条件に、該アドレスをnurseryオブジェクト参照リストから削除する（ステップ５０４）。そして処理は終了する。
【００７０】
図６に示す処理は、スタックフレームの破棄に応答して実行され、ステップ６００において、ＪＶＭ２０４は、スキャン不要領域開始ポインタが破棄されるスタックフレームを指すか否かを判定する。スキャン不要領域開始ポインタが破棄されるスタックフレームを指す場合（ステップ６００：ＹＥＳ）、続いて、ＪＶＭ２０４は、スキャン不要領域開始ポインタに、スタックフレーム破棄後の新しいスタック・ポインタの値を設定する（ステップ６０２）。ステップ６００において、スキャン不要領域開始ポインタが破棄されるスタックフレームを指さない場合（ステップ６００：ＮＯ）、又は、ステップ６０２の後処理は終了する。
【００７１】
以上、実施形態を用いて本発明の説明をしたが、本発明の技術範囲は上記実施形態に記載の範囲には限定されない。上記の実施形態に、種々の変更または改良を加えることが可能であることが当業者に明らかである。従って、そのような変更または改良を加えた形態も当然に本発明の技術的範囲に含まれる。
【００７２】
なお、特許請求の範囲、明細書、及び図面中において示した装置、システム、プログラム、及び方法における動作、手順、ステップ、及び段階等の各処理の実行順序は、特段「より前に」、「先立って」等と明示しておらず、また、前の処理の出力を後の処理で用いるのでない限り任意の順序で実現しうることに留意すべきである。また、前の処理の出力を後の処理で用いる場合でも、前の処理と後の処理の間に他の処理が入ることは可能である場合があること、又は間に他の処理が入るように記載されていても前の処理を後の処理の直前に行うよう変更することも可能である場合があることも留意されたい。特許請求の範囲、明細書、及び図面中の動作フローに関して、便宜上「まず、」、「次に、」、「続いて、」等を用いて説明したとしても、この順で実施することが必須であることを必ずしも意味するとは限らない。
【図１】
0005889270.tif 000002
【図２】
0005889270.tif 000003
【図３】
0005889270.tif 000004
【図４】
0005889270.tif 000005
【図５】
0005889270.tif 000006
【図６】
0005889270.tif 000007