本開示の態様は、コンピュータ・システムにおけるガベージ・コレクションに関し、より具体的な態様は、ガベージ・コレクションについて到達不可能なリソースをマーク付けすることに関する。本開示は、必ずしもそのような応用に限定されないが、本開示の様々な態様は、この文脈を用いた様々な例の議論を通して認識することができる。
典型的なコンピュータ・システムは、リソース(本明細書では「オブジェクト」とも呼ばれる)が、それらのコンピュータ・システム上で開発中に又は実時間での使用中に実行されるプロセスによって必要とされるときに、それらのリソースをメモリに格納する。リソースを要求したプログラムが変化したり、プログラムの用途が変化したりすると、そのプログラムの動作に以前には必要であったリソースが不要となることがある。不必要にシステム・メモリを使用しているリソースの除去によって、システムをより速く且つより滑らかに動作させることができる。このために、多くのコンピュータ・システムは、コンピュータ・システムによってもはや必要とされないリソースをメモリから削除するように設計されたガベージ・コレクションの方式を組み入れている。しかし、ガベージ・コレクションの方法が、効果的にそれらリソースを削除するためには、もはや必要のないリソースを識別する必要がある。
幾つかのコンピュータ・システムにおいて、不要なリソースは、メモリ内のいずれかの他のリソースがそれらの不要なリソースを参照するかどうかに基づいて、識別することができる。例えば、多くのコンピュータ・システムは、「ポインタ」の使用によりリソースを追跡する。「ポインタ」は、本明細書で用いられる場合、別のリソースを識別してその位置を与える、リソースの参照を指す。ポインタは、コンピュータ・システムが第1のリソースの利用中に又は利用後に使用する必要があり得る1つ又は複数のリソースを識別するために、リソースによって使用される。メモリ内のリソースが、それ自体がルート・リソース(例えば、プログラム又はプロセスの実行時に初めにロードされるオブジェクト)にトレース・バックされ得るリソース内のポインタによって識別されるとき、そのオブジェクトは「到達可能」と言われる。このことが当てはまらないいずれのオブジェクトも「到達不可能」と言われる。
メモリ内の到達不可能なオブジェクトは、コンピュータ・システムに何の利益を与えることもなくメモリ空間を占有する。それらは到達不可能なために、どのプログラムもそのオブジェクトを使用することができない。従って、到達不可能なリソースを識別し、メモリから除去することが有益である。幾つかのコンピュータ・システムは、到達不可能なオブジェクトに割り当てられたメモリを解放するために、ガベージ・コレクションを使用する。ガベージ・コレクションは、典型的には、到達可能なオブジェクトのリストを決定し、次いでリストされないオブジェクトを削除するために、オグジェクトの間のポインタの分析を含む。
例えば、幾つかのガベージ・コレクションの方法は、システム又はプロセスのルート・オブジェクトとみなされるものを識別することによって開始する。ルート・オブジェクトは、本明細書で使用される場合、典型的には、特定のプロセス又はプログラム内の、システムによってロードされた第1のオブジェクトの形態をとる。ルート・オブジェクトは、典型的には、コンピュータ・システムによるルート・オブジェクトへの迅速且つ確実なアクセスをもたらす、メモリの構造化されたセクションに格納される。それらは、例えば、整理されたメモリのメモリ・スタック又は他のセクションに存在することがある。迅速且つ確実なアクセスと、ルート・オブジェクトがシステムによってプロセスのためにロードされたベース・オブジェクトであるということとから、定義上、ルート・オブジェクトは到達可能である。
ルート・オブジェクトは、多くの場合、ルート・オブジェクトがロードされた後でプロセスを行うために必要な他のオブジェクトへのポインタを含む。例えば、プロセスのためのリソース・オブジェクトは、そのプロセスを実行するために、順番に使用されることが必要なリンクされたリスト項目を含むことができる。リンクされたリストにおいて、各々のストレージ・オブジェクトは、リスト内の次のオブジェクトの位置へのポインタを含む。従って、リストのルートにおいて、ルート・オブジェクトは、リンクされたリスト内の次のオジェクトへのポインタを含むことになる。
本明細書で使用される場合、第2のオブジェクトへのポインタを含む第1のオブジェクト(例えば、ルート・オブジェクト)は、本明細書においては、その第2のオブジェクトに関する「ペアレント」又は「ペアレント・オブジェクト」と呼ばれる。一方、第2のオブジェクトは、そのペアレントの「チャイルド」又は「チャイルド・オブジェクト」と呼ばれる。第2のオブジェクトがさらに第3のオブジェクトへのポインタを含む場合、第2のオブジェクトはまた、第3のオブジェクトのペアレントと呼ばれ、第3のオブジェクトは、第2のオブジェクトのチャイルドと呼ばれる。さらに、第1のオブジェクトは、第3のオブジェクトの「グランドペアレント」又は「グランドペアレント・オブジェクト」と呼ばれ、一方、第3のオブジェクトは、第1のオブジェクトの「グランドチャイルド」又は「グランドチャイルド・オブジェクト」と呼ばれる。あるオブジェクトのチルドレン、グランドチルドレンなどを総称して、本明細書では、そのオブジェクトの「子孫」又は「子孫オブジェクト」と呼ぶことができる。
多くのメモリ・システムにおいて、ルート・オブジェクトは、メモリの極めて整理されたセクション(例えば、スタック・メモリ)に格納されるが、子孫オブジェクトは、多くの場合、メモリのあまり整理されていない、あまり管理されていない、自由な浮動セクション(例えば、ヒープ・メモリ)に格納される。整理されていないメモリは通常、メモリの整理されたセクションより大きく且つよりフレキシブルであるが、その中でオブジェクトの位置を特定することは、ディレクションなしにはより難しい。このため、オブジェクトへのポインタは、通常、メモリのこの未整理のセクション内のそのオブジェクトのアドレスを与えるか又は計算を可能にする情報を含む。換言すれば、ペアレント・オブジェクト内の、チャイルド・オブジェクトへのポインタを分析することによって、そのチャイルド・オブジェクトのメモリ位置を決定することができる。
次いで、ルート・オブジェクトのどの子孫オブジェクトもまた、ルート・オブジェクトをその子孫に結びつける一連のポインタを通して到達可能ということになる。同様に、ルート・オブジェクトの子孫ではないどのオブジェクトも到達可能ではない。従って、多くのガベージ・コレクション・システムは、ルート・オブジェクトの子孫オブジェクトを識別することによって、メモリから除去すべきオブジェクトを識別する。例えば、典型的なガベージ・コレクション・システムは、ルート・オブジェクトを識別し(例えば、メモリ・スタック内で)それを「到達可能」とマーク付けすることによって開始する。次いで、システムは、他のオブジェクト(例えば、ルート・オブジェクトのチルドレン)へのポインタについてルート・オブジェクトを分析する。チャイルド・オブジェクトへのポインタを発見すると、ガベージ・コレクションを行う典型的なシステムは、次に、そのチャイルド・オブジェクトのメモリ内での位置を識別することができ、そのメモリ位置にあるオブジェクトがシステムのメモリ管理システムにおいて「到達可能」であると記録する。ルート・オブジェクトのチルドレンのポインタを分析することにより、同様のプロセスを、ルート・オブジェクトのグランドチルドレンなどについても行うことができる。ルート・オブジェクトの子孫の全てのポインタが分析されると(従って、全ての到達可能オブジェクトが識別されると)、あらゆる残りの(即ち、マーク付けされない、子孫でない)オブジェクトは、到達不可能とみなされ、なぜなら、それらの到達不可能なオブジェクトにポイントする、ルート・オブジェクトに由来するポインタが存在しないからである。
多くの現代のシステムにおいて、複数のプロセッサ・スレッドが、メモリ管理システムにおいてオブジェクトを同時に「到達可能」としてマーク付けするように働くことができる。しかし、このことは、時々、幾つかのマーク付け技術を用いて他のスレッドによって行われた以前のマーク付け作業をスレッドが重複して行うことにつながる可能性がある。例えば、スレッドが、それ自体が到達可能とマーク付けされたペアレント・オブジェクトの位置を特定する場合、そのスレッドは、ペアレント・オブジェクトがポイントするチャイルド・オブジェクトが、それら自体の位置が特定されてマーク付けされているかどうか判断する方法を有しない可能性がある。このため、これらのマーク付け技術は、ナイーブと呼ばれることがある。ナイーブなマーク付け技術においては、スレッドは、ペアレント・オブジェクトの全てのポインタを分析して、それらのチルドレンが既にマーク付けされている場合でも、そのペアレントのチルドレンの位置を特定するために時間を費やす可能性がある。それは、これらのマーク付けシステムにおいては、ペアレントのチャイルドがマーク付けされているかどうかを判断する唯一の方法が、メモリ内でそのチャイルドの位置を特定することだからである。そのチャイルド・オブジェクトがマーク付けされていない場合には、そのペアレントのチルドレンをマーク付けするためにスレッドを効率的に使用することができるはずである。しかし、そのチャイルド・オブジェクトが別のスレッドによって既にマーク付けされている場合、それらが既にマーク付けされたことを見つけるためだけにそのチャイルド・オブジェクトの位置を特定する時間を費やすことは、相当な時間を浪費する可能性がある。特に、ペアレント・オブジェクトが多くのチルドレンを有する場合、このことは著しい非効率を招く可能性がある。
例えば、第1のスレッドがメモリを走査することができ、ペアレント・オブジェクトへの参照を見出し、そのペアレント・オブジェクトのメモリ・アドレスの位置を特定し、それを「到達可能」とマーク付けすることができる。第1のスレッドは次に、そのペアレント・オブジェクト内のポインタを走査し、そのチルドレンのメモリ・アドレスの位置を特定し、それらをまた「到達可能」とマーク付けすることを開始するができる。第1のスレッドが「到達可能」とマーク付けした後に、さらに第2のスレッドがメモリを走査し、ペアレント・オブジェクトへの参照を見つけた場合、ナイーブなマーク付け技術を使用する場合にはそのペアレントのチルドレンが既にマーク付けされているかどうか判断することができないことになる。このことは、第2のスレッドに選択をもたらし、即ち、ペアレントのチルドレンの位置を特定して、別のスレッドが既に行った作業を重複するリスクをもたらすか、チルドレンをスキップしてマーク付けされないままにしておくリスクをもたらす可能性がある。
ナイーブなマーク付け技術に伴う問題に対処するために、幾つかのシステムは、ガベージ・コレクションのために到達可能オブジェクトを識別するときに、3色マーク付け技術を使用する。3色マーク付けにおいて、オブジェクトは、3つの状態、(1)マーク付けされていない(業界ではしばしば「白」と呼ばれる)、(2)マーク付けされており、マーク付けされていないチルドレンを伴う(業界ではしばしば「グレイ」と呼ばれる)、及び(3)マーク付けされており、マーク付けされていないチルドレンを伴わない(業界ではしばしば「黒」と呼ばれる)に分類することができる。3色マーク付けにおいて、あるスレッドが「白」オブジェクト(即ち、マーク付けされていないオブジェクト)への参照の位置を特定したとき、そのスレッドは、オブジェクトを「グレイ」とマーク付けし、次いで、そのオブジェクトがマーク付けされていないチルドレンにポイントするかどうかを判断する。
グレイ・オブジェクトが、マーク付けされていないチルドレンにポイントしない場合、それは「黒」とマーク付けすることができる。グレイ・オブジェクトが、マーク付けされていないチルドレンにポイントする場合、スレッドは、メモリ内でそれらの位置を特定し、それらを同様にマーク付けする(典型的にはグレイとして)。幾つかの実施において、ペアレントは、全てのチルドレンがグレイとしてマーク付けされたときにのみ、黒に切り替えることができる。他の実装において、ペアレントは、プロセス中に早期に(例えば、スレッドがそのチルドレンをマーク付けし始めるとすぐに)黒に切り替えることができる。
3色マーク付け技術においては、スレッドが、黒とマーク付けされているオブジェクトへの参照を見つけたときに、そのオブジェクト及びそのオブジェクトのすべてのチルドレン(もしあれば)がいずれもマーク付けされていると結論づけることができ、したがって、スレッドは、他のオブジェクトへの参照のために、メモリの走査に移って継続することができる。一方、スレッドは、グレイ・オブジェクトを見つけたときに、そのグレイ・オブジェクトがマーク付けされていないチルドレンへのポインタを含むと結論づけることができ、それらのチルドレンの位置を特定してマーク付けすることを開始することができる。
例えば、第1のスレッドは、メモリを走査し、あるペアレント・オブジェクトへの参照をみつけ、そのペアレント・オブジェクトのメモリ・アドレスの位置を特定し、それを「グレイ」とマーク付けすることができる。次に、第1のスレッドは、そのペアレント・オブジェクト内のポインタを走査し、チルドレンのメモリ・アドレスの位置を特定し、チルドレンを同様にグレイとマーク付けすることを開始することができる。全てのチルドレンがマーク付けされると、第1のスレッドは、ペアレントを「黒」に変更することができることになる。
この例において、第2のスレッドが、第1のスレッドがペアレントを黒とマーク付けする前に、そのペアレントへの参照の位置を特定する場合、その第2のスレッドは、ペアレントが「グレイ」であるために、ペアレントがマーク付けされていないチルドレンへのポインタを有することを知ることになる。第2のスレッドは次に、第1のスレッドがそれらのチルドレンの位置を特定してマーク付けすることを助けることができる。一方、第1のスレッドがペアレントを黒とマーク付けした後に、第2のスレッドがペアレントへの参照の位置を特定した場合、第2のスレッドは、ペアレントがマーク付けされているばかりでなく、そのペアレントのチルドレンの位置も同様に特定されてマーク付けされていることを知ることになる。この状況で、第2のスレッドは、ペアレントをマーク付けしたり、ポインタについてペアレントを走査したり、ポイント先のアドレスにあるチャイルド・オブジェクトを探してそれらがマーク付けされていることを確認したりするために、時間を費やすべきではないと結論づけることになる。3色マーク付けがなければ、第2のスレッドは、確信を持ってこれらの判断を下すことができないであろう。
しかし、第1のスレッドがペアレントのチルドレンの1つを「グレイ」とマーク付けした後に、第2のスレッドが、メモリ走査中にそのチャイルドに遭遇した場合、第2のスレッドは、このチャイルドは別のスレッドによってマーク付けされているが、まだマーク付けされていない別のチルドレン(即ち、初めのペアレントのグランドチルドレン)へのポインタを有すると結論づける可能性がある。従って、第2のスレッドは次に、初めのチャイルド内のポインタを分析し、初めのペアレントのグランドチルドレンの位置を特定してマーク付けすることを開始することができることになる。重要なことに、このことは、第1のスレッドが、初めのペアレントの他のチルドレンの位置を特定して識別するためにまだ作業しているのと同時に起こる可能性がある。このように、3色マーク付けを使用することにより、第1及び第2のスレッドは、互いの努力が重複する危険性なく、同じファミリー・ツリーについて効率的に作業することができる。
残念なことに、3色マーク付け技術は、全てのメモリ・システムにおいて容易に実装できるものではない。例えば、幾つかのシステムは、ビットマップと呼ばれるメモリ構造を用いて、管理されていないメモリ・スペース(例えば、ヒープ・スペース)の占有を追跡する。ビットマップは典型的には、各々がメモリの対応する領域を表すインデックス位置の1次元アレイ(即ち、ヒープ・スペース内の連続的な一連のバイト)の形態をとる。これらのメモリの対応する領域は、メモリ内の特定の位置(場合により、「メモリ位置」又は「メモリ・アドレス」と呼ばれる)で開始し、インデックス位置に対応するこれらの特定の位置は、インデックス位置に基づいて決定することができる(例えば、「4」のインデックス位置に200を掛けて、対応する「800」のメモリ位置を計算し、25のインデックス位置に200を掛けて、対応する「5,000」のメモリ位置を計算する)。ビットマップ内の各々のインデックス位置が対応する領域のサイズは、メモリ・システムの設定に基づいてカスタマイズすることができる。例えば、幾つかのシステムにおいては、各々のインデックス位置は、整理されていないメモリ空間内の2バイト領域を指すことができ、他のシステムにおいては、各々のインデックスは、メモリ内の20バイト領域に対応することができる。
典型的なビットマップにおいて、各々のインデックス位置は単一ビットからなり、これは、オンにする(例えば、「1」に設定する)又はオフにする(例えば、「0」に設定する)ことができる。従って、ビットマップでは、単一ビットは、メモリ内の遥かに大きな領域に関する情報を伝えることができる。例えば、各々のインデックス位置が、メモリ内の8バイト領域に対応する場合、ビットマップの各々のビットは、実際には、メモリ内の約64バイトの情報を伝える。これらのビットをオン及びオフにすることは、対応する領域に関する異なる情報(例えば、その領域が占有されているかどうか、その領域が分析されているかどうか、その領域が頻繁に使用されるデータを含むかどうか、又は、その領域が到達可能なオブジェクトを保持するかどうか)を追跡するために使用することができる。この情報は、メモリの相対的に大きな部分を単一ビットのサイズで表現することできるので、それらの小さいストレージ要件から、ビットマップが好まれることが多い。
ビットマップを使用する典型的なシステムが、ガベージ・コレクションを行うとき、あるメモリ位置で始まるオブジェクトは、そのメモリ位置に対応するビットマップ内のインデックス位置を見つけて、そのインデックス位置におけるビットを「0」から「1」へ切り替えることによって、マーク付けされる。しかし、各々のインデックス位置は、0又は1のいずれかにすることができるだけなので、対応するオブジェクトを、3つの状態(例えば、「白」、「グレイ」、又は「黒」)のうちの1つにマーク付けすることは困難である。従って、あるスレッドが、ビットマップ内の「1」とマーク付けされたメモリの領域への参照を調べるとき、そのスレッドは、メモリの対応する位置に、位置を特定された到達可能なオブジェクトが存在すると結論づけることはできるが、そのオブジェクトがマーク付けされていない何れかのチルドレンを含むかどうか結論づけることができない可能性がある。換言すれば、メモリ情報を追跡するためにビットマップを使用する幾つかのシステムにおいて、3色マーク付け技術は、ナイーブなマーク付け技術と同じ不利益を被る。
本開示の幾つかの実施形態は、ナイーブなマーク付けシステムの不利益を避ける方法で、ビットマップを使用するシステムにおける3色マーク付けを実施する。例えば、幾つかのシステムにおいては、整理されていないメモリは、ヒープ・メモリを形成する。前述のように、ビットマップ内の各々のビット(換言すれば、各々のインデックス位置)は、メモリの同じサイズの領域に対応する。各々のビットが対応するメモリの領域のサイズは、本明細書ではアライメント・サイズと呼ばれる。例えば、ビットマップ内の各々のビットが4バイトに対応する場合、ビットマップのアライメント・サイズは4バイトとなる。これらのシステムにおいて、アライメント・サイズ(例えば、4バイト)より大きいオブジェクトがメモリに加えられる場合、そのオブジェクトが格納される領域は、ビットマップ内の1ビットより多くを要することになる。換言すれば、8バイトのオブジェクトが、4バイトのアライメント・サイズを有するシステム内のヒープ・スペースの領域に加えられる場合、その領域は、そのビットマップの2ビットに対応することになる。
本開示の幾つかの実施形態は、ガベージ・コレクションのためにオブジェクトをマーク付けするときに、オブジェクトのサイズとアライメント・サイズとを比較することによって、3色マーク付けを実施する。例えば、幾つかの実施形態は、アライメント・サイズより大きいオブジェクトを識別することができる。これらのオブジェクトは、ビットマップ内の少なくとも2つのインデックス位置に対応するメモリ領域を占有するので、少なくとも2つのビットマップ・ビットを使用して、それらのオブジェクトが「白」とみなされるか、又は「ブラック」若しくは「グレイ」とマーク付けされているかを識別することができる。
例えば、幾つかの実施形態において、オブジェクトが、ビットマップの2つのインデックス位置に対応するヒープ・スペース内の領域を占有した場合、第1のインデックス位置を使用して、その領域内のオブジェクトがマーク付けされたかどうかを示すことができる。換言すれば、第1のビットは、オブジェクトが白であることを示すようにオフにする(即ち、「0」に設定する)ことができ、オブジェクトが黒又はグレイであることを示すようにオンにする(即ち、「1」に設定する)ことができる。この例において、第2のインデックス位置は、オブジェクトがグレイであることを示すためにオフにし、オブジェクトが黒であることを示すためにオンにすることができる。従って、これらの実施形態において、「00」と読まれるビットマップ内のビットのセットが白のオブジェクト(例えば、マーク付けされていないオブジェクト)を示し、「10」と読まれるビットマップ内のビットのセットがグレイのオブジェクト(例えば、マーク付けされているが、マーク付けされていないチルドレンへのポインタを含むオブジェクト)を示し、「11」と読まれるビットのセットが黒のオブジェクト(例えば、マーク付けされており、ポインタを含まないか又はマーク付けされたチルドレンへのポインタを含むオブジェクト)を示すことになる。従って、アライメント・サイズより大きいオブジェクトを識別することにより、本開示の実施形態は、ビットマップを使用するときでも、3色マーク付けが可能なヒープ・スペース内のオブジェクトを効率的に識別する。
アライメント・サイズより大きなオブジェクトを個々に識別することは、3色マーク付けが可能なオブジェクトを識別するための有用な方法であり得るが、本開示の実施形態を用いる3色マーク付けは、ヒープ・スペース内の全てのオブジェクトがアライメント・サイズより大きい場合には、特に有利である。これらの場合において、3色マーク付けは、ヒープ・スペースを通して用いることができ、ナイーブなマーク付け技術の非効率性を排除する。
従って、本開示の幾つかの実施形態は、ヒープ・スペースについての最小のオブジェクト・サイズがアライメント・サイズより大きいかどうか識別することを試みることができる。「最小のオブジェクト・サイズ」を有するヒープ・スペースにおいて、ヒープ・スペースは、メモリ内の連続するバイトの同じサイズのブロックに分割される。これらの同じサイズのブロックは、本明細書では、最小オブジェクト・サイズと呼ばれることがある。例えば、メモリ・システムは、16バイトの最小オブジェクト・サイズを有することができる。この例において、メモリは、16バイトの同じサイズの領域に分割されることになり、どの16バイト領域も1つより多くのオブジェクトを含まないことになる。従って、実際にサイズが7バイトしかないオブジェクトがメモリ内に格納される場合、そのオブジェクトには、1つの16バイト領域全体を割り当てることができる。一方、17バイトのオブジェクトがメモリに加えられる場合、これは、2つの連続する16バイト領域に割り当てることができる。このために、メモリ内の「オブジェクトのサイズ」は、メモリ内でそのオブジェクトに割り当てられる全体の領域のサイズを指す場合があると理解することができる。
メモリ・システムにおいて最小オブジェクト・サイズを使用すると、ビットマップ内でメモリ位置をインデックス位置へマッピングする効率を向上させることができる。しかし、アライメント・サイズより大きな最小オブジェクト・サイズを識別することにより、最小オブジェクト・サイズを使用することで、本開示の実施形態を通して、3色マーク付けの効率をさらに向上させることができる。例えば、ヒープ・スペースについての最小オブジェクト・サイズを、8バイトとすることができる。6バイトのオブジェクトがヒープ・スペースに加えられる場合、そのオブジェクトには、依然として最小オブジェクト・サイズ(8バイト)が割り当てられることになる。一方、10バイトのオブジェクトがヒープ・スペースに加えられる場合、そのオブジェクトには、最小オブジェクト・サイズの2つの領域(16バイト)が割り当てられることになる。
最小オブジェクト・サイズをアライメント・サイズと比較することにより、本開示の実施形態は、メモリ内の全てのオブジェクトに対して、少なくとも2ビットが使用可能かどうか判断することができる。例えば、最小オブジェクト・サイズが、アライメント・サイズの少なくとも2倍である場合、メモリ内の各々のオブジェクトは、ビットマップ内の少なくとも2ビットに対応することになる。これらの状況においては、2つのビットマップ・ビットを用いる3色マーク付けは、メモリ内のあらゆるオブジェクトについて行うことができる。
図1は、本開示の実施形態による、ビットマップを用いて3色マーク付けを行う方法100を示す。方法100は、例えば、コンピュータ・システム401などのより大きなコンピュータ・システムのストレージ・コントローラ又は中央処理ユニットの1つ又は複数のスレッドによって、実行することができる。方法100は、整理されたメモリ・セクション(例えば、メモリ・スタック)、整理されていないメモリ・セクション(例えば、ヒープ・スペース)、及びビットマップを有するシステムで実行することができる。
図1は、スレッドがメモリ内のマーク付けされていないオブジェクトの位置を特定するブロック102において開始する。ブロック102は、マーク付けされていないオブジェクトのメモリ位置(「メモリ・アドレス」とも呼ばれる)を識別することを含む。幾つかの場合、ブロック102は、スレッドが、初めにスタック・スペースなどのメモリの整理されたセクションにおいてマーク付けされていないルート・オブジェクトの位置を特定することを含むことができる。例えば、スレッド実施の方法100は、ガベージ・コレクションのまさに始めに、ルート・オブジェクトについてスタック・スペースを初めに走査するときに、ブロック102を実行することができる。一方、幾つかの場合において、ブロック102は、ヒープ・スペースなどのメモリの整理されていないセクションにおいて、マーク付けされていないオブジェクトの位置を特定することを含むことができる。例えば、スレッド実施の方法100は、ペアレント・オブジェクト内のマーク付けされていないチャイルド・オブジェクトへのポインタをたどることによって、ブロック102を行うことができる。
ブロック104において、スレッドは、ビットマップとメモリとの間で、メモリ内のマーク付けされていないオブジェクトのサイズがアライメント・サイズより十分に大きいかどうかを判断する。前述のように、ビットマップ内の各々のインデックス位置(即ち、ビットマップ内の各々のビット)は、メモリの同じサイズの領域に対応する。ビットマップ内の各々のビットが対応するメモリのこのサイズは、アライメント・サイズと呼ばれる。従って、マーク付けされていないオブジェクトが、メモリ内でアライメント・サイズより小さくなる場合、マーク付けされていないオブジェクトは、ビットマップ内の1ビットのみによって参照することができる。例えば、ビットマップ内の各々のビットは、メモリの16バイト領域に関する情報を提供することができる。この例において、アライメント・サイズは、16バイトである。メモリ内のマーク付けされていないオブジェクトのサイズが、10バイトのみである場合、ビットマップ内の1ビットのみによって参照することができる。マーク付けされていないオブジェクトがビットマップ内の1ビットのみで参照される場合、そのオブジェクトに関連するマーク付け情報を表すために複数のビットマップ・ビットを使用することは便利ではない。しかし、マーク付けされていないオブジェクトのサイズが20バイトである場合、16バイトのアライメント・サイズを有する前述の例において、そのオブジェクトによって消費されるメモリ内の全スペースを追跡するために、1つより多くのビットマップ・ビットを必要とすることになる。マーク付けされていないオブジェクトが、ビットマップ内の2ビットによって参照される場合、そのオブジェクトに関するマーク付け情報を表すために、複数のビットマップ・ビットを使用することが可能となる。
幾つかの実施形態において、ブロック104は、マーク付けされていないオブジェクトがアライメント・サイズより大きいかどうか判断することを含むだけでなく、マーク付けされていないオブジェクトがどれほど大きいかを判断することができる。例えば、マーク付けされていないオブジェクトがアライメント・サイズの少なくとも2倍大きいことは、有利な場合がある。この例において、オブジェクトのサイズがアライメント・サイズの2倍の大きさであれば、オブジェクトのサイズは、アライメント・サイズより単に「十分に大きい」とすることができる。このことは、例えば、メモリ内のオブジェクトの最小サイズがアライメント・サイズに比べて小さいメモリ・システムにおいて有利な場合がある。例えば、メモリ・システムが、最小オブジェクト・サイズは1バイトであるが、アライメントサイズは8バイトと指定することができる。この例においては、メモリ内の9バイトのオブジェクトは、追跡するために2ビットマップ・ビットを必要とする領域を占有する。しかし、そのオブジェクトは、第2のビットマップ・ビットによって追跡される8バイト領域のうちの1バイトしか消費しないので、その領域は、他の7つの1バイト・オブジェクトを含むこともできる。従って、そのような例では、9バイト・オブジェクトのマーク付けを追跡するために第2のビットマップ・ビットを使用すると、紛らわしい可能性がある。
しかし、ブロック104が、オブジェクト・サイズがアライメント・サイズの少なくとも2倍の大きさであるかどうかを判断する場合、ブロック104は、そのオブジェクトが格納されているメモリの領域を追跡するために2ビットマップ・ビットが割り当てられるであろうということを確認するために使用することができ、従って2ビットマップ・ビットがそのオブジェクトを白、グレイ、又は黒とマーク付けするために使用可能であろうと確認することができる。例えば、システム内のアライメント・サイズが4バイトであった場合、ブロック104は、マーク付けされていないオブジェクトのサイズが少なくとも8バイトであるかどうかを判断するために使用することができる。
幾つかの実施形態において、ブロック104は、オブジェクト自体がアライメント・サイズより十分に大きいかどうかを判断するために使用できるばかりでなく、オブジェクトに割り当てられた領域が十分に大きいかどうかを判断するために使用することができる。例えば、幾つかのメモリ・システムは、オブジェクトを説明するヘッダー又はプロセス中の次のオブジェクトに関する情報を与えるフッターを全てのオブジェクトに付加することを要求する場合がある。そのようなメモリ・システム上で方法100を実施するとき、ブロック104は、オブジェクトのヘッダー及びフッターを考慮に入れることがある。例えば、アライメント・サイズが8バイトであり、オブジェクトのサイズは8バイトであるがさらに8バイトのヘッダーを有する場合、ブロック104は、そのオブジェクトは、ヘッダーを考慮に入れると、アライメント・サイズの2倍の大きさであると結論づけることができる。
幾つかの実施形態において、ブロック104の判断は、システム全体(又はメモリ・スペース全体)に基づいて行うことができる。換言すれば、ブロック104において、スレッドは、特定のオブジェクトがアライメント・サイズより十分に大きいかどうかではなく、メモリ・スペースについての最小オブジェクト・サイズがアライメント・サイズより十分に大きいかどうかを判断する場合がある。例えば、ヒープ・スペース内でオブジェクトの位置が特定されている場合、ブロック104を実行しているスレッドは、その最小オブジェクト・サイズがアライメント・サイズより十分に大きい(例えば、2倍大きい)かどうかを判断することができる。これらの実施形態においては、ブロック104は、ブロック102の前に、さらには、ガベージ・コレクション・プロセス又はガベージ・コレクション・プロセスのためのマーク付けが開始される前に、実行することができる。むしろ、ブロック104は、これらの実施形態においては、予備的な措置として行われ、システム構成として格納することができる。
スレッドが、ブロック104において、オブジェクト・サイズ(例えば、ヘッダー、フッターなどを含むオブジェクトに割り当てられるメモリ領域)がアライメント・サイズより十分に大きくないと判断する場合、スレッドは、オブジェクトの3色マーク付けを行うために複数のビットマップ・ビットを使用するべきではないと結論づけ、方法100はブロック106において終了する。しかし、スレッドが、オブジェクト・サイズがアライメント・サイズより十分に大きいと判断する場合、スレッドはブロック108へ進み、そこでスレッドは、マーク付けされていないオブジェクトの対応するインデックス位置(又は、位置(複数))を識別する。
ブロック108において、スレッドは、マーク付けされていないオブジェクト(例えば、ブロック102において識別された可能性がある)のメモリ・アドレスをビットマップのインデックス位置に変換することができる計算を、行うことができる。例えば、スレッドは、メモリ・アドレスを所定の整数(例えば、100)で割り、次いで、得られた商から別の所定の整数(例えば、200)を差し引くことができる。この計算の結果、マーク付けされていないオブジェクトが格納されているメモリ領域のメモリ・アドレスに対応するインデックス位置を識別することができる。
幾つかの実施形態において、ブロック108は、複数のインデックス位置を識別することを含むことができる。計算されるインデックス位置の数は、アライメント・サイズに関するマーク付けされていないオブジェクトのサイズに依存し得る。例えば、マーク付けされていないオブジェクトのサイズがアライメント・サイズの4倍の大きさである場合、マーク付けされていないオブジェクトが格納される全領域は、ビットマップ内の4ビットに対応することになる。この例において、ブロック108を実行するスレッドは、複数のビットマップ・ビットがそのマーク付けされていないオブジェクトに対応することを検出することができ、それらのビットマップ・ビットすべてを識別することができる。幾つかの実施形態において、スレッドは、ビットマックのビットのうちの2つのみを、2つより多くのビットがマーク付けされていないオブジェクトに対応する場合でも識別することができる。例えば、マーク付けされていないオブジェクトによって占有される領域が、10ビットマップ・ビットに対応する場合、スレッドは、初めの2つのインデックス位置(例えば、そのオブジェクトによって占有される最小のメモリ・アドレスに対応する2つのインデックス位置)、又は、最後の2つのインデックス位置(例えば、そのオブジェクトによって占有される最大のメモリ・アドレスに対応する2つのインデックス位置)のみを識別することができる。
スレッドが、マーク付けされていないオブジェクトのメモリ位置に対応するインデックス位置を識別すると、スレッドは、ブロック110に進み、それらのインデックス位置の「第1」にビットを設定する。換言すれば、スレッドは、第1のインデック位置におけるビットを「0」から「1」へ切り替える。第1のビットを1に設定することにより、スレッドは、ブロック102において位置を特定されたマーク付けされていないオブジェクトが、今やマーク付けされて「グレイ」又は「黒」とみなされるという事実を記録する。このマーク付けにより、その第1のインデックス位置に対応するメモリ・アドレスに到達可能なオブジェクトが存在し、従ってそのオブジェクトは削除されるべきではないことを、ガベージ・コレクティング・システムに通知する。
ブロック110において、「第1」のインデックス位置が何であるかを判断することは、システムの他の構成に依存し得る。例えば、幾つかの実施形態において、第1のインデックス位置は、マーク付けされていないオブジェクトについてのビットマップを走査するようにスレッドがプログラムされる方向に依存し得る。本質的ではないが、「第1」のインデックス位置は、スレッドがビットマップを走査しているときにブロック108で識別されたインデックス位置のうち、スレッドが初めに遭遇するインデックス位置であることが、有利な場合がある。スレッドが、ビットマップを上昇方向(即ち、小さいメモリ・アドレスに対応するインデックス位置で開始し、大きいメモリ・アドレスに対応するインデックス位置へ向かって進む)へ走査するようにプログラムされる場合、「第1の」インデックス位置は、マーク付けされていないオブジェクトによって占有される最小のメモリ・アドレスに対応するインデックス位置とすることができる。しかし、スレッドが、ビットマップを下降方向に走査するようにプログラムされる場合、「第1の」インデックス位置は、マーク付けされていないオブジェクトによって占有される最大のメモリ・アドレスに対応するインデックス位置とすることができる。幾つかの実施形態において、ブロック108において識別された2つより多くの対応するインデックス位置が存在する場合でも、「第1の」インデックス位置は、常に、マーク付けされていないオブジェクトによって占有される2つの最小の又は2つの最大のメモリ・アドレスに対応する2つのインデックス位置のうちの1つとすることができる。これらの実施形態において、これらの2つのインデックス位置の「第1の」インデックス位置は、依然として、スレッドの走査方向によって決定することができる。換言すれば、スレッドがビットマップを下降方向に走査するようにプログラムされ、ブロック108において4つのインデックス位置が識別される場合、ブロック110は、第1のビットとして、2番目に低いインデックス位置(即ち、マーク付けされていないオブジェクトによって占有される、2番目に小さいメモリ・アドレスに対応するインデックス位置)に設定することができる。これは、ビットマップを下降方向に走査するスレッドによって、2つの最低インデックス位置のうちの2番目に低いインデックス位置が初めに分析されることになるためである。
ブロック110において、第1の識別されたインデックス位置においてビットが設定されると、「マーク付けされていない」オブジェクトは「グレイ」とマーク付けされているとみなすことができる。このことは、そのオブジェクト自体は位置を特定されてマーク付けされているが、マーク付けされていないチルドレンを有する可能性があることを意味する。従って、ブロック110において、オブジェクトをグレイとマーク付けした後、スレッドは、ブロック112において、オブジェクトが少なくとも1つのマーク付けされていないチャイルドを有するかどうか判断することに進む。例えば、スレッドは、メモリ内のオブジェクトのコンテンツを分析し、オブジェクトが他のオブジェクト(即ち、チルドレン)へのいずれかのポインタを含むかどうか判断することができる。殆どの場合、直前にマーク付けされていないオブジェクトがチルドレンを有すると、それらのチルドレンは、マーク付けされていないことになる。従って、殆どの場合、スレッドは、ブロック112において、グレイ・オブジェクトがチルドレンへのポインタを有する場合、それらのチルドレンはマーク付けされていないと安全に推定することができる。
スレッドが、ブロック112において、グレイ・オブジェクトがマーク付けされていないチルドレンを何も有していないと判断する場合、スレッドは、ブロック114で、第2の識別されたインデックス位置においてビットを設定することができる。この第2のインデックス位置は、ブロック108においてオブジェクトが格納されているメモリ領域に対応すると識別されたインデックス位置の中にあるはずである。第2の位置にあるビットが設定されると、「グレイ」オブジェクトは、「黒」とみなすことができる。このことは、オジェクトの位置が特定されて「到達可能」とマーク付けされていることと、オブジェクトが、位置が特定されず「到達可能」とマーク付けされていないチルドレンを持たないこととを意味する。
ブロック114における「第2のインデックス位置」は、第1のインデックス位置に隣接するものとすることができる。これは、3色マーク付けに使用するためにビットマップ内の2つの隣接するビットしか必要としないので、有利な場合がある。例えば、スレッドがオブジェクトについてのビットマップを走査していた場合、スレッドは、第1のインデックス位置においてビットがセットされていることを発見することがある。スレッドは、到達可能オブジェクトが、その第1のインデックス位置に対応するメモリ・アドレスにおいてメモリに格納されていると結論づけることができる。次の隣接するビットを走査することにより、スレッドは、そのオブジェクトがいずれかのマーク付けされていないチルドレンを有するかどうかを結論づけることもできる。
選択された第2のインデックス位置がビットマップ内の上流(即ち、より大きいメモリ・アドレス)にあるか又はビットマップ内の下流にあるかは、ブロック110に関連して論じられたように、システムのスレッドの走査位置に基づいて決定することができる。例えば、スレッドが、ビットマップを上昇方向に(即ち、低メモリ・アドレスに対応するインデックス位置から、高メモリ・アドレスに対応するインデックス位置へ)走査するようにプログラムされる場合、より高いインデックス位置を選択することが有利な場合がある。
スレッドが、ブロック112において、オブジェクトが少なくとも1つのマーク付けされていないチャイルドを有すると判断する場合、スレッドは、ブロック116において、グレイ・オブジェクト内のチャイルドへのポインタをたどって進み、メモリ内でそのチャイルドの位置を特定する。メモリ内でチャイルドの位置を特定することは、システムの仕様及びポインタのコンテンツに基づいて変わる場合があるが、通常、チャイルドは、チャイルドのメモリ・アドレスを決定するためのポインタ内の情報を用いて位置が特定される。チャイルドのメモリ・アドレスの位置が特定されると、スレッドは、そのメモリ・アドレスのビットマップにおける対応するインデックス位置を識別することもできる。チャイルドのメモリ・アドレスについての対応するインデックス位置が識別されると、スレッドは、そのインデックス位置に、チャイルドの位置が特定されてマーク付けされていることを示すビットを設定することができる。このことは、そのインデックス位置に対応するメモリ位置に到達可能なオブジェクトが格納されていることを、他のスレッドに対して示すことになる。
ブロック116においてチャイルドの位置が特定されてマーク付けされた後、スレッドは、ブロック114に進み、ペアレント・オブジェクト(即ち、ブロック102において位置が特定されたオブジェクト)についての第2のインデックス位置においてビットを設定する。スレッドは、次に、ブロック118において、ペアレント・オブジェクトが、他のいずれかのチルドレンへのポインタを含むかどうか判断する。ペアレントがさらに別のチルドレンを有する場合、スレッドは、ブロック120において、次のチャイルドの位置を特定してマーク付けすることに進む。この位置の特定及びマーク付けは、ブロック116の位置の特定及びマーク付けに類似する場合がある。ブロック120において、次のチャイルドの位置が特定されてマーク付けされた後、スレッドは、ブロック118に戻り、さらにチルドレンが存在するかどうかを再び判断する。スレッドが、ブロック118において、ペアレント・オブジェクト(即ち、ブロック102において位置が特定されたオブジェクト)がチャイルド・オブジェクトへのさらなるポインタを有しないと判断する場合、スレッドは、ブロック116において方法100を終了する。
図1は、方法100に関する動作の1つの可能な順序を示すが、幾つかの他の実施形態においては、動作の正確なタイミング及び順序は、前述とは異なるものとすることができる。例えば、幾つかの実施形態においては、ブロック114における、ペアレントについて第2のビットを設定する正確なタイミングは、システム構成、ペアレントによってポイントされるチルドレンの数、並びに、チャイルド及びペアレントのオブジェクトの近接度に依存する可能性がある。
例えば、幾つかの実施形態において、第2のインデックス位置におけるビットは、ペアレント・オブジェクトのチルドレンの閾値パーセンテージが「グレイ」とマーク付けされるまで(例えば、ブロック116、118及び120を通して)、ブロック114において設定されない可能性がある。このことは、ブロック114において第2のビットを設定することによって、ビットマップを走査している他のスレッドに、ペアレントの全てのチルドレンがマーク付けされていることを知らせることができるので、ペアレントが多数のチルドレンを有する場合に有利な可能性がある。これは、努力の重複を避けるために有用であり得るが、ペアレントが非常に多くのチルドレンを有する場合に、他のスレッドがペアレントのチルドレンをマーク付けするのを支援することを妨げる可能性がある。このような場合には、努力のある程度の重複の可能性が、多数のチルドレンの位置を特定してマーク付けする複数のスレッド作業の性能上の利点を正当化する。従って、閾値(例えば、50)を超える多数のチルドレンを伴うペアレント・オブジェクトについて、スレッドは、ペアレントのチルドレンの閾値数がマーク付けされるまで、ブロック114で第2のインデックス位置におけるビットを設定しなくて良い。例えば、ペアレント(例えば、ブロック102においてマーク付けされたオブジェクト)が、100のチルドレンを有する場合、閾値は、50%(即ち、ブロック118及び120の49回の繰り返しと、ブロック116の1回の繰り返しの和)に設定することができる。
一方、幾つかの場合、スレッドは、チャイルドのマーク付けプロセスにおいてそうすることが好都合である限り、ブロック114において第2のビットを設定することを試みることができる。ブロック114において第2のビットをいつ設定するのが「好都合である」かは、ペアレント・オブジェクト(即ち、ブロック102において位置が特定されたオブジェクト)とチャイルド・オブジェクトの近接度に依存し得る。例えば、ブロック116において位置が特定されてマーク付けされたチャイルド・オブジェクトが、ビットマップ内でペアレント・オブジェクトに近い場合、ペアレントの第2のビットとチャイルドの第1のビットとを、同時に(例えば、同じ「コンペア・アンド・スワップ」命令内で)マーク付けすることができる。しかし、ブロック116において位置が特定されてマーク付けされたチャイルド・オブジェクトが、ペアレント・オブジェクトに近くない場合、スレッドは、ブロック118及びブロック120の繰り返し中に位置が特定されるペアレントにチャイルドが接近するまで、ブロック114において第2のビットを設定することを遅らせることができる。例えば、スレッドは、ブロック116から、ブロック118及びブロック120まで直接進むことができる。ブロック118及びブロック120の第1の繰り返し中に位置が特定されるチャイルドが、ペアレント・オブジェクトの近くで位置が特定される場合、スレッドは、ブロック114において、そのチャイルドをマーク付けすることができ、同時に第2のビットを設定することができる。そうでない場合には、スレッドは、再びブロック114を遅らせ、ブロック118及びブロック120のさらに別の繰り返しを行う。この実施は、ビットマップ内のビットを設定する余分な命令を防ぐことができるが、ブロック114における第2のインデックス位置のビットの設定を遅らせることは、別のスレッドが、ビットマップ走査でペアレント・オブジェクトを見つけ、それがグレイであると結論づけ、そのペアレントのチルドレンを走査することによって(例えば、ブロック116、118、及び120を実行することによって)努力を重複する機会を増やす可能性がある。従って、このようにブロック114を遅らせるようにプログラムされたスレッドは、ブロック118及び120の繰り返しの閾値数が行われた(例えば、20の繰り返し)後にブロック114を行うようにプログラムすることもできる。
幾つかの場合においては、スレッドが、ブロック114において第2のインデックス位置の第2のビットを可能な限り早く設定することが有利な場合がある。第2のインデックス位置においてビットを設定することにより、効果的にペアレント・オブジェクトを「黒」とマーク付けし、これによって、ペアレント・オブジェクトの全てのチルドレンがマーク付けされていることをスレッドに知らせる。これにより、次に、スレッドがポインタについてペアレントを分析することをスキップして、他のオブジェクトについてビットマップを走査することに移ることができることを意味する。このことは、別のスレッドがビットマップ走査でペアレント・オブジェクトの位置を特定し、別のスレッドによって既にマーク付けされ位置が特定されたチルドレンの位置を特定してマーク付けする試みを開始する危険性を最小にすることができる。
理解のために、図2A~2Cは、本開示の実施形態による、3色マーク付けをビットマップで用いることができるメモリ・システム200の抽象的な図を示す。図2Aは、あらゆるオブジェクトが到達可能とマーク付けされる前のメモリ・システム200の初めの図を示す。
メモリ・システム200は、システムのコンピュータ処理ユニット(CPU)によって重度に管理されるメモリの整理され秩序だった部分であるスタック・スペース202を含む。メモリ・システム200はさらに、システムについての殆どのリソース・オブジェクトを格納することができる、より大きくあまり整理されていないセクション・メモリであるヒープ・スペース204を含む。ヒープ・スペース204のコンテンツは、各々が単一ビットを含むインデックス位置の1次元マトリックスであるビットマップ206によって、マッピングすることができる。インデックス位置208及び210は、それぞれヒープ・スペース204の最大及び最小のメモリ・アドレスに対応する、ビットマップ206のビットを表す。ビットマップ206は、理解し易くするために、19のインデックス位置のみを含むように表されているが、実際には、ビットマップは、それらが追跡するヒープ・スペースのサイズに応じて、遥かに多数のインデックス位置を含むことができる。
スタック・スペース202は、ルート・オブジェクト212を含む。スレッドは、メモリ・システム200において3色マーク付けを行うことを開始するときに、ルート・オブジェクト212を分析して、チャイルド・オブジェクト(オブジェクト214)へのポインタを発見することができる。そのポインタを分析することによって、スレッドに、ヒープ・スペース204におけるそのオブジェクトのメモリ内の位置(即ち、メモリ・アドレス)を与えることができる。この分析は、破線216によって表される。チャイルド214のメモリ・アドレスを用いて、スレッドは、オブジェクト214が格納されているヒープ・スペース204の領域のメモリ・アドレスに対応する、ビットマップ内のインデックス位置(インデックス位置216~222)を、識別することができる。この識別は、破線224によって表され、これらのインデックス位置を包含するビットマップの領域は、破線ボックス226によって示される。
図2Bは、メモリ・システム200の次の図を示す。図2Bにおいて、スレッドは、インデックス位置216においてビットを設定し、インデックス位置216に対応するメモリ・アドレスに到達可能なオブジェクト(オブジェクト214)が存在することを示す。メモリ・システム200のスレッドは、オブジェクトについてのビットマップを上昇方向に(即ち、インデックス位置208からインデックス位置210へ向かって)走査するようにプログラムすることができるため、スレッドは、ビットマップ領域226における他のいずれかのビットではなく、インデックス位置216を選択することができる。なぜなら、インデックス位置216は、ビットマップ206を走査するスレッドが遭遇することになる領域226内の初めのインデックス位置であるからである。従って、インデックス位置216において設定されたビットは、そのインデックス位置に対応するオブジェクト(オブジェクト214)が「グレイ」とマーク付けされていることをスレッドに示すことができるが、そのオブジェクトについての次のインデックス位置(例えば、インデックス位置218)に設定されたビットは、そのオブジェクトが「黒」とマーク付けされていることを示すことができる。
インデックス位置216においてビットを設定すると、スレッドは、オブジェクトを分析して、オブジェクトがチャイルド・オブジェクト234、236、及び238への3つのポインタ228、230、及び232を有することを発見することができる。それらのポインタの1つを分析することにより、スレッドは、メモリにおけるチャイルド・オブジェクトの1つの位置を決定することができる。例として、破線240は、スレッドがポインタ232を分析してチャイルド・オブジェクト238のメモリ・アドレスを決定する分析を示す。
チャイルド・オブジェクト238のメモリ・アドレスを決定することにより、スレッドは次に、チャイルド・オブジェクト238によって占有されるメモリの領域に対応する、ビットマップ206内の対応するインデックス位置を識別することができる。この識別は、破線242によって示され、チャイルド・オブジェクト238の位置が特定されたメモリ領域にインデックス位置が対応する、ビットマップ206の領域244を示す。インデックス位置246は、それらのインデックス位置の「最下位」であり、ビットマップを上昇方向に走査するスレッドによって走査されることになる。
図2Cは、メモリ・システム200の次の図を示す。図2Cにおいて、チャイルド・オブジェクト238に対応するインデックス位置を識別したスレッドは、インデックス位置246でビットを設定している。このことは、実際に、チャイルド・オブジェクト238を「グレイ」とマーク付けし、ビットマップを走査している他のスレッドに対して、到達可能なオブジェクトがインデックス位置246に関連付けられるメモリ領域を占有していることを知らせる。図2Cに描かれているように、チャイルド・オブジェクト238に対応するインデックス位置を識別したスレッドは、インデックス位置218でもビットを設定している。
互いに隣接し、いずれも設定されている216及び218のビットは、到達可能なオブジェクトがインデックス位置216及び218に関連付けられるメモリ領域を占有していることと、さらに、その到達可能なオブジェクトのチルドレンは、位置を特定してマーク付けする必要がないこととを、ビットマップを走査している他のスレッドに知らせる。換言すれば、インデックス位置218にビットを設定することは、オブジェクト214のマーク付けを「グレイ」から「黒」へ効果的に変更する。幾つかの実施形態において、インデックス位置218のビットは、オブジェクト214の第1のチャイルドがマーク付けされたときに、設定されている可能性がある。このことは、他のいずれかのスレッドが、オブジェクト214の残りのチルドレン(例えば、チャイルド・オブジェクト234及び236)の位置を特定してマーク付けするのを助けることを妨げることになるが、重複努力(例えば、他のスレッドが、チャイルド・オブジェクト238の位置を、それが既にマーク付けされた後で決定してマーク付けするように試みること)を防ぐための助けにもなる。幾つかの実施形態において、インデックス位置218のビットは、オブジェクト214の最後のチャイルドがマーク付けされたときに設定することができる。このことは、別のスレッドが、オブジェクト214の残りのチルドレンの位置を特定してマーク付けすることを助ける機会を増やすことになるが、重複努力の機会を増やすことにもなる。幾つかの実施形態において、インデックス位置218のビットは、オブジェクト214の閾値数のチルドレンがマーク付けされた後で、又は、インデックス位置218と同じコンペア・アンド・スワップ命令でマーク付けすることができるチャイルド・オブジェクトと同時に、設定することができる。
スレッドは、オブジェクト214によってポイントされた全てのチャイルド・オブジェクトの位置を特定してマーク付けすると、グレイ・オブジェクトについてビットマップ206を走査し続けることができる。グレイ・オブジェクトの位置を特定すると、スレッドは、ヒープ・スペース内でそのオブジェクトの位置を特定することができ、そのポインタをたどって、そのチルドレンの位置を特定してマーク付けを開始することができる。
図2Aに示されるように、ビットマップ206を上昇方向に走査する(例えば、インデックス位置208で開始し、210に向かって走査する)スレッドは、初めにインデックス位置216に設定されたビットを発見することができる。メモリ・システムにおけるスレッドは、オグジェクトをグレイとマーク付けするときに「最下位」のインデックス位置にビットを設定するようにプログラムされている場合、スレッドは、インデックス位置216に設定されたビットを検出することによって、到達可能なオブジェクト(即ち、オブジェクト214)がインデックス位置に対応するヒープ・スペース領域に位置すること、及び、その到達可能なオブジェクトが「グレイ」とマーク付けされていることを、仮定することができる。しかし、スレッドは、オブジェクト214のチルドレンが位置を特定されてマーク付けされているかどうかを直ちに知ることにはならない。スレッドは、次のインデックス位置であるインデックス218を走査することによって、しかし、そのオブジェクトが「黒」とマーク付けされたことを推論できることになる(特に、最小オブジェクト・サイズがアライメント・サイズより大きいシステムにおいて)。これは、オブジェクト214の全てのチルドレンがマーク付けされているか、又はマーク付けされている最中であることを意味する。従って、スレッドは、ヒープ・スペース内でオブジェクト214の位置を特定したり、オブジェクト214のポインタをたどってそのチルドレンの位置を特定してマーク付けしたりする必要がないと結論づけることができる。
オブジェクト214が「黒」とマーク付けされたことを理解すると、スレッドは、インデックス位置に設定されたビットを検出するまで、ビットマップ206を走査し続けることができる。これにより、インデックス位置216に設定されたビットと同様に、対応するヒープ・スペース位置にある到達可能なオブジェクト(即ち、チャイルド・オブジェクト238)が「グレイ」とマーク付けされたことを再びスレッドに知らせる。しかし、次のインデックス位置(インデックス位置248)を走査し、そこにビットが設定されたことを検出することによって、スレッドは、チャイルド・オブジェクト238がまだ「黒」とマーク付けされていなかったと結論づけることができる。これは、チャイルド・オブジェクト238が、位置を特定してマーク付けする必要がある幾つかの到達可能なチルドレンを有する可能性がまだあることを意味することになり、従ってスレッドは、ヒープ・スペース内でチャイルド・オブジェクト238の位置を特定し、ポインタについてそれを分析することを開始することができる。
前述のように、第1のスレッドは、オブジェクト214のチルドレンの位置を特定してマーク付けしながら、インデックス位置218におけるビットを設定した可能性がある。従って、第2のスレッドは、そのオブジェクト214が「黒」とマーク付けされたことを検出し、その検出に基づいて走査を続け、そのチャイルド・オブジェクト238が「グレイ」とマーク付けされたがまだ「黒」とマーク付けされていないことを検出することができる。従って第2のスレッドは、第1のスレッドが依然としてチャイル・オブジェクト234及び236の位置を特定してマーク付けしている一方で、チャイルド・オブジェクト238のチルドレンの位置を特定してマーク付けすることを開始することができる。このようにして、3色マーク付けを用いて、メモリ・システム200内で、重複努力の可能性を減らしながら複数のスレッドの効率の利益を得ることができる。
図3は、到達可能なオブジェクトについてビットマップを走査する方法300を示す。方法300はさらに、ガベージ・コレクションのために到達可能なオブジェクトを識別中のスレッドが本開示の3色マーク付けシステムを使用することができる方法を示す。例えば、方法300は、図2Cに関連して論じられた「第2のスレッド」によって実行することができる。
方法300は、スレッドがインデックス位置を走査するブロック302で開始する。幾つかの場合において、そのインデックス位置は、ビットマップ内の第1のインデックス位置であるかもしれないし、次のインデックス位置であるかもしれない。幾つかの実施形態において、スレッドは、ビットマップを上昇方向に走査することができ、一方、他の実施形態においては、スレッドは、ビットマップを下降方向に走査することができる。ブロック304において、スレッドは、ブロック302において走査されたインデックス位置(本明細書では第1のインデックス位置と呼ばれる)においてビットが設定されている(即ち、「1」に設定されている)かどうか判断する。スレッドが、ビットが設定されていないと判断する場合、スレッドは、第1のインデックス位置に対応する位置におけるメモリには、「到達可能」とマーク付けされたオブジェクトが格納されていないと結論づけることができる。スレッドは次に、ブロック306において、ビットマップ内の次のインデックス位置(本明細書では「第2の」インデックス位置と呼ばれる)を走査することに進む。スレッドは次に、ブロック304に戻り、第2のインデックス位置においてビットが設定されているかどうか判断する。
ブロック304において、スレッドが、インデックス位置に(例えば、第2のインデックス位置に)ビットが設定されていると判断する場合、スレッドは、到達可能なオブジェクトがそのインデックス位置に対応するメモリ・アドレスに配置されていると結論づけることができる。このことは、オブジェクトが「グレイ」とマーク付けされたことをスレッドに知らせるが、スレッドは、そのインデックス位置(例えば、第2のインデックス位置)のみに基づいて、オブジェクトが「黒」とマーク付けされたかどうかを判断することができない。従って、スレッドは次に、ブロック308において、ビットマップ内の次のインデックス位置(本明細書では「第3の」インデックス位置と呼ばれる)を走査することに進む。
スレッドは次に、ブロック310において、次のインデックス位置(例えば、第3のインデックス位置)にビットが設定されているかどうか判断する。スレッドが、ビットが設定されていると判断する場合、スレッドは、2つの先行するインデックス位置(例えば、第2及び第3のインデックス位置)にビットが設定されたので、オブジェクトが「黒」とマーク付けされたと結論づけることができる。このことは、マーク付けされたオブジェクトのチルドレンが位置を特定されてマーク付けされていること、又は、十分な数のチルドレンがマーク付けされており、チルドレンに関して支援はもはや必要ないことを、スレッドに知らせることになる。従って、スレッドは、ブロック312において黒オブジェクトをスキップすることができ、ブロック306における次のインデックス位置を走査することに進むことができる。
一方、ブロック310において、スレッドが、ビットが設定されていないと判断する場合、2つの先行するインデックス位置(例えば、第2及び第3のインデックス位置)のうちの1つのみが設定されたビットを示したので、オブジェクトは「グレイ」とマーク付けされたと結論づけることができる。このことは、マーク付けされたオブジェクトのチルドレンがマーク付けされていなかったこと、又は、マーク付けされたチルドレンの数が十分に少ないので、残りのチルドレンの位置を特定してマーク付けするための支援が有益であることを、スレッドに知らせる。従って、スレッドは次に、ブロック314において「グレイ」オブジェクトをメモリからロードし、ブロック316においてオブジェクト内のポインタを分析し、そのチルドレンの位置を特定してマーク付けすることに進むことになる。このようにして、複数のスレッドを用いて、重複努力の望ましくないリスクを受けることなく、メモリ内の到達可能なオブジェクトの位置を特定してマーク付けすることができる。
図4は、本開示の実施形態に従って使用することができる例示的なコンピュータ・システム401の代表的な主要コンポーネントを示す。図示された個々のコンポーネントは、例のためだけに示されたものであり、必ずしもそれらの変化形だけではない。コンピュータ・システム410は、プロセッサ410、メモリ420、入力/出力インターフェース(本明細書ではI/O又はI/Oインターフェースとも呼ばれる)430、及びメイン・バス440を含むことができる。メイン・バス440は、コンピュータ・システム401の他のコンポーネントのための通信経路を提供することができる。幾つかの実施形態において、メイン・バス440は、特殊用途デジタル信号プロセッサ(図示されず)のような他のコンポーネントに接続することができる。
コンピュータ・システム401のプロセッサ410は、1つ又は複数のCPU412を含むことができる。プロセッサ410はさらに、CPU412のための命令及びデータの一時的なストレージを提供する1つ若しくは複数のメモリ・バッファ又はキャッシュを含むことができる。CPU412は、キャッシュ又はメモリ420から提供される入力に対して命令を実行することができ、その結果をキャッシュ又はメモリ420へ出力することができる。CPU412は、本開示の実施形態と整合する1つ又は複数の方法を行うように構成された1つ又は複数の回路を含むことができる。幾つかの実施形態において、コンピュータ・システム401は、比較的大きいシステムに典型的な複数のプロセッサ410を含むことができる。しかし、他の実施形態においては、コンピュータ・システム410は、1つのCPU412のみを有する単一のプロセッサとすることができる。
コンピュータ・システム401のメモリ420は、メモリ・コントローラ422、及び、データを一時的に又は永続的に格納するための1つ又は複数のメモリ・モジュール(図示せず)を含むことができる。幾つかの実施形態において、メモリ420は、データ及びプログラムを格納するためのランダム・アクセス半導体メモリ、ストレージ・デバイス、又はストレージ媒体(揮発性又は不揮発性)を含むことができる。メモリ・コントローラ422は、プロセッサ410と通信し、メモリ・モジュールにおける情報のストレージ及び検索を容易にすることができる。メモリ・コントローラ422は、I/Oインタ-フェース430と通信し、メモリ・モジュールにおける入力及び出力のストレージ及び検索を容易にすることができる。いくつかの実施形態において、メモリ・モジュールは、デュアル・インライン・メモリ・モジュールとすることができる。
I/Oインターフェース430は、I/Oバス450、端末インターフェース452、ストレージ・インターフェース454、I/Oデバイス・インターフェース456、及びネットワーク・インターフェース458を含むことができる。I/Oインターフェース430は、メイン・バス440をI/Oバス450に接続することができる。I/Oインターフェース430は、プロセッサ410及びメモリ420からの命令及びデータを、I/Oバス450の種々のインターフェースへ向けることができる。I/Oインターフェース430はさらに、I/Oバス450の種々のインターフェースからの命令及びデータを、プロセッサ410及びメモリ420へ向けることができる。種々のインターフェースは、端末インターフェース452、ストレージ・インターフェース454、I/Oデバイス・インターフェース456、及びネットワーク・インターフェース458を含むことができる。幾つかの実施形態において、種々のインターフェースは、上記のインターフェースのサブセットを含むことができる(例えば、産業用途の埋め込み型コンピュータ・システムは、端末インターフェース452及びストレージ・インターフェース454を含まない場合がある)。
限定されるものではないが、メモリ420、プロセッサ410、及びI/Oインターフェース430を含むコンピュータ・システム401を通して、論理モジュールは、失敗及び1つ又は複数のコンポーネントに対する変更を、ハイパーバイザ又はオペレーティング・システム(図示せず)に伝えることができる。ハイパーバイザ又はオペレーティング・システムは、コンピュータ・システム401内の利用可能な種々のリソースを割り当てることができ、メモリ420内のデータの位置及び種々のCPU412に割り当てられたプロセスの位置を追跡することができる。要素を結びつけるか又は再編成する実施形態において、論理モジュールの能力の態様は、組み合わせるか又は再分散することができる。これらの変化形は、当業者には明白であろう。
本発明は、システム、方法若しくはコンピュータ・プログラム製品又はそれらの組み合わせを、いずれかの可能な技術的詳細レベルで統合したものとすることができる。コンピュータ・プログラム製品は、プロセッサに本発明の態様を実行させるためのコンピュータ可読プログラム命令を有するコンピュータ可読ストレージ媒体(単数又は複数)を含むことができる。
コンピュータ可読ストレージ媒体は、命令実行デバイスにより使用される命令を保持及び格納できる有形デバイスとすることができる。コンピュータ可読ストレージ媒体は、例えば、これらに限定されるものではないが、電子ストレージ・デバイス、磁気ストレージ・デバイス、光ストレージ・デバイス、電磁気ストレージ・デバイス、半導体ストレージ・デバイス、又は上記のいずれかの適切な組み合わせとすることができる。コンピュータ可読ストレージ媒体のより具体的な例の非網羅的なリストとして、以下のもの、すなわち、ポータブル・コンピュータ・ディスケット、ハード・ディスク、ランダム・アクセス・メモリ(RAM)、読み出し専用メモリ(ROM)、消去可能プログラム可能読み出し専用メモリ(EPROM又はフラッシュ・メモリ)、スタティック・ランダム・アクセス・メモリ(SRAM)、ポータブル・コンパクト・ディスク読み出し専用メモリ(CD-ROM)、デジタル多用途ディスク(DVD)、メモリ・スティック、フロッピー・ディスク、パンチカード若しくは命令がそこに記録された溝内の隆起構造のような機械的にエンコードされたデバイス、及び上記のいずれかの適切な組み合わせが挙げられる。本明細書で使用される場合、コンピュータ可読ストレージ媒体は、電波、又は他の自由に伝搬する電磁波、導波管若しくは他の伝送媒体を通じて伝搬する電磁波(例えば、光ファイバ・ケーブルを通る光パルス)、又はワイヤを通って送られる電気信号などの、一時的信号自体として解釈されない。
本明細書で説明されるコンピュータ可読プログラム命令は、コンピュータ可読ストレージ媒体からそれぞれのコンピューティング/処理デバイスに、又は、例えばインターネット、ローカル・エリア・ネットワーク、広域ネットワーク若しくは無線ネットワーク、又はそれらの組み合わせなどのネットワークを介して外部コンピュータ又は外部ストレージ・デバイスにダウンロードすることができる。ネットワークは、銅伝送ケーブル、光伝送ファイバ、無線伝送、ルータ、ファイアウォール、スイッチ、ゲートウェイ・コンピュータ若しくはエッジ・サーバ、又はそれらの組み合わせを含むことができる。各コンピューティング/処理デバイスにおけるネットワーク・アダプタ・カード又はネットワーク・インターフェースは、ネットワークからコンピュータ可読プログラム命令を受け取り、コンピュータ可読プログラム命令を転送して、それぞれのコンピューティング/処理デバイス内のコンピュータ可読ストレージ媒体内に格納する。
本発明の動作を実行するためのコンピュータ可読プログラム命令は、アセンブラ命令、命令セットアーキテクチャ(ISA)命令、機械命令、機械依存命令、マイクロコード、ファームウェア命令、状態設定データ、集積回路のための構成データ、又は、Smalltalk、C++などのオブジェクト指向プログラミング言語、及び、「C」プログラミング言語若しくは類似のプログラミング言語などの従来の手続き型プログラミング言語を含む1つ又は複数のプログラミング言語の任意の組み合わせで記述されるソース・コード又はオブジェクト・コードとすることができる。コンピュータ可読プログラム命令は、完全にユーザのコンピュータ上で実行される場合もあり、一部がユーザのコンピュータ上で、独立型ソフトウェア・パッケージとして実行される場合もあり、一部がユーザのコンピュータ上で実行され、一部が遠隔コンピュータ上で実行される場合もあり、又は完全に遠隔コンピュータ若しくはサーバ上で実行される場合もある。最後のシナリオにおいて、遠隔コンピュータは、ローカル・エリア・ネットワーク(LAN)若しくは広域ネットワーク(WAN)を含むいずれかのタイプのネットワークを通じてユーザのコンピュータに接続される場合もあり、又は外部コンピュータへの接続がなされる場合もある(例えば、インターネットサービスプロバイダを用いたインターネットを通じて)。幾つかの実施形態において、例えば、プログラム可能論理回路、フィールド・プログラマブル・ゲート・アレイ(FPGA)、又はプログラム可能論理アレイ(PLA)を含む電子回路は、本発明の態様を実施するために、コンピュータ可読プログラム命令の状態情報を利用することによってコンピュータ可読プログラム命令を実行して、電子回路を個別化することができる。
本発明の態様は、本発明の実施形態による方法、装置(システム)及びコンピュータ・プログラム製品のフローチャート図若しくはブロック図又はその両方を参照して説明される。フローチャート図若しくはブロック図又はその両方の各ブロック、並びにフローチャート図若しくはブロック図又はその両方におけるブロックの組み合わせは、コンピュータ可読プログラム命令によって実装できることが理解されるであろう。
これらのコンピュータ可読プログラム命令を、コンピュータ又は他のプログラム可能データ処理装置のプロセッサに与えて機械を製造し、それにより、コンピュータ又は他のプログラム可能データ処理装置のプロセッサによって実行される命令が、フローチャート若しくはブロック図又は両方の1つ又は複数のブロック内で指定された機能/動作を実施するための手段を作り出すようにすることができる。コンピュータ、プログラム可能データ処理装置若しくは他のデバイス又はそれらの組み合わせを特定の方式で機能させるように指示することができるこれらのコンピュータ・プログラム命令を、コンピュータ可読媒体内に格納することもでき、それにより、そのコンピュータ可読媒体内に格納された命令が、フローチャート若しくはブロック図又はその両方の1つ又は複数のブロックにおいて指定された機能/動作の態様を実施する命令を含む製品を含むようにすることもできる。
コンピュータ可読プログラム命令を、コンピュータ、他のプログラム可能データ処理装置、又は他のデバイス上にロードして、一連の動作ステップをコンピュータ、他のプログラム可能データ処理装置、又は他のデバイス上で行わせてコンピュータ実施のプロセスを生産し、それにより、コンピュータ又は他のプログラム可能装置上で実行される命令が、フローチャート若しくはブロック図又は両方の1つ又は複数のブロックにおいて指定された機能/動作を実行するためのプロセスを提供するようにすることもできる。
図面内のフローチャート及びブロック図は、本発明の様々な実施形態による、システム、方法、及びコンピュータ・プログラム製品の可能な実装の、アーキテクチャ、機能及び動作を示す。この点に関して、フローチャート内の各ブロックは、指定された論理機能を実装するための1つ又は複数の実行可能命令を含む、モジュール、セグメント、又はコードの一部を表すことができる。幾つかの代替的な実装において、ブロック内に示される機能は、図に示される順序とは異なる順序で生じることがある。例えば、連続して示される2つのブロックは、関与する機能に応じて、実際には実質的に同時に実行されることもあり、又はこれらのブロックはときとして逆順で実行されることもある。ブロック図若しくはフローチャート図又は両方の各ブロック、及びブロック図若しくはフローチャート図又はその両方におけるブロックの組み合わせは、指定された機能又は動作を実行する、又は専用のハードウェアとコンピュータ命令との組み合わせを実行する、専用ハードウェア・ベースのシステムによって実装できることにも留意されたい。
本開示の種々の実施形態の説明は、例証の目的のために提示されたが、これらは、網羅的であること、又は開示した実施形態に限定することを意図するものではない。当業者には、説明される実施形態の範囲から逸脱することなく、多くの修正及び変形が明らかであろう。本明細書で用いられる用語は、実施形態の原理、実際の適用、又は市場に見られる技術に優る技術的改善を最もよく説明するため、又は、当業者が、本明細書に開示される実施形態を理解するのを可能にするために選択された。