これらは, Garbage Collection 処理用の補助クラス. より具体的に言うと, GC 処理をマルチスレッド化するためのクラス (See: here for details).
全ての GangTask クラスの基底クラス (See: here for details).
((cite: hotspot/src/share/vm/utilities/workgroup.hpp))
// An abstract task to be worked on by a gang.
// You subclass this to supply your own work() method
class AbstractGangTask VALUE_OBJ_CLASS_SPEC {
なお, このクラス自体は abstract class であり, 実際に使われるのはサブクラス.
((cite: hotspot/src/share/vm/utilities/workgroup.hpp))
// The abstract work method.
// The argument tells you which member of the gang you are.
virtual void work(int i) = 0;
See: here for details
特殊な AbstractGangTask クラス (See: here for details).
通常の AbstractGangTask に加えて, OopTaskQueueSet と ParallelTaskTerminator を内部に格納している. (何のため?? #TODO)
((cite: hotspot/src/share/vm/utilities/workgroup.hpp))
class AbstractGangTaskWOopQueues : public AbstractGangTask {
(現状では CMS 専用のクラスである模様)
なお, このクラス自体は abstract class であり, 実際に使われるのはサブクラス.
CMSRefProcTaskProxy クラスのスーパークラスとして(のみ)使用されている.
See: here for details
GangWorker スレッド全体を管理するクラスの基底クラス (See: here for details).
((cite: hotspot/src/share/vm/utilities/workgroup.hpp))
// Class AbstractWorkGang:
// An abstract class representing a gang of workers.
// You subclass this to supply an implementation of run_task().
class AbstractWorkGang: public CHeapObj {
なお, このクラス自体は abstract class であり, 実際に使われるのはサブクラス.
((cite: hotspot/src/share/vm/utilities/workgroup.hpp))
// Run a task, returns when the task is done (or terminated).
virtual void run_task(AbstractGangTask* task) = 0;
See: here for details
GangWorker スレッドと WorkGang オブジェクト (GangWorker スレッドの取りまとめ役) の間で GangTask 情報を受け渡す際に使用される補助クラス.
(より具体的に言うと, AbstractWorkGang::internal_worker_poll() と GangWorker::loop() で使用される補助クラス. 各 GangWorker スレッドが取りまとめ役である WorkGang から次の GangTask を取得する際に使用される.)
((cite: hotspot/src/share/vm/utilities/workgroup.hpp))
class WorkData: public StackObj {
単なる構造体のようなクラス.
内部には以下のフィールド(のみ)を含む (そして, メソッドはこれらのフィールドへのアクセサメソッドのみ).
(コメントにも「struct でもよかったけどアクセサメソッドが欲しかったのでクラスにした」と書かれるほどシンプル)
((cite: hotspot/src/share/vm/utilities/workgroup.hpp))
// This would be a struct, but I want accessor methods.
private:
bool _terminate;
AbstractGangTask* _task;
int _sequence_number;
See: here for details
AbstractWorkGang クラスのサブクラス (See: here for details).
((cite: hotspot/src/share/vm/utilities/workgroup.hpp))
// Class WorkGang:
class WorkGang: public AbstractWorkGang {
なお, このクラス自体は abstract class であり, 実際に使われるのはサブクラス.
See: here for details
WorkGang を用いた並列 GC において, 実際の GC 処理を行う WorkerThread クラス (See: here for details).
((cite: hotspot/src/share/vm/utilities/workgroup.hpp))
// Class GangWorker:
// Several instances of this class run in parallel as workers for a gang.
class GangWorker: public WorkerThread {
AbstractWorkGang オブジェクトの _gang_workers フィールドに(のみ)格納されている.
(正確には, このフィールドは GangWorker の配列を格納するフィールド. この中に, 使用される全ての GangWorker オブジェクトが格納されている)
(なお, 実際には AbstractWorkGang は abstract class であり, サブクラスの FlexibleWorkGang 内の同名のフィールドにのみ格納されている模様)
WorkGang::allocate_worker() というファクトリメソッドが用意されており, その中で(のみ)生成されている. そして, このファクトリメソッドは, 現在は以下のパスで(のみ)呼び出されている.
* SharedHeap オブジェクトの初期化時 SharedHeap::SharedHeap() -> WorkGang::initialize_workers() -> WorkGang::allocate_worker() * G1GC の ConcurrentMark の初期化時 ConcurrentMark::ConcurrentMark() -> WorkGang::initialize_workers() -> WorkGang::allocate_worker()
See: here for details
WorkGang クラスの具象サブクラス (See: here for details).
((cite: hotspot/src/share/vm/utilities/workgroup.hpp))
class FlexibleWorkGang: public WorkGang {
以下の箇所に(のみ)格納されている.
以下の箇所で(のみ)生成されている.
See: here for details
GangWorker スレッド間でバリア同期を取るためのクラス (See: here for details).
((cite: hotspot/src/share/vm/utilities/workgroup.hpp))
// A class that acts as a synchronisation barrier. Workers enter
// the barrier and must wait until all other workers have entered
// before any of them may leave.
class WorkGangBarrierSync : public StackObj {
(現状では G1GC 専用のクラスである模様)
ConcurrentMark オブジェクトの first_overflow_barrier_sync フィールドおよび _second_overflowbarrier_sync フィールドに(のみ)格納されている.
See: here for details
複数の GangWorker スレッド間で, (ある程度大きな単位で) 負荷分散を行うためのクラス (See: here for details).
((cite: hotspot/src/share/vm/utilities/workgroup.hpp))
// A class to manage claiming of subtasks within a group of tasks. The
// subtasks will be identified by integer indices, usually elements of an
// enumeration type.
class SubTasksDone: public CHeapObj {
あらかじめ, 分散したい各処理には, それぞれ unique な int 値を割り振っておく.
SubTasksDone の中身は int 配列になっている.
配列中の値が 1 であれば該当の処理に誰かが着手済みであることを示し, 逆に配列中の値が 0 であれば誰も手をつけていないことを示す.
SubTasksDone::is_task_claimed() が false を返せば, 自分がその処理を取得できたことになる.
(SubTasksDone オブジェクトは SubTasksDone::all_tasks_completed() が呼び出された回数をカウントしている. 回数がスレッド数に等しくなれば, 全処理が終了したとして SubTasksDone オブジェクトは初期状態(全ての種別の処理が未処理の状態)に戻る. 初期状態に戻す処理は SubTasksDone::clear() を呼び出すことで行われる.)
See: here for details
特殊な SubTasksDone クラス (See: here for details).
SubTasksDone クラスと異なり, GangWorker スレッドは自分が取得する処理を指定できない. 代わりに, 現在残っている処理の中から「一番番号が小さいもの」が勝手に割り振られて返される. (この挙動は, 処理にあらかじめ番号が振れない場合に便利, とのこと. 例えば, Remembered Set のスキャン処理等をスレッド数に応じた数で動的に分割したい, 等).
(なお, SubTasksDone と違ってこちらは StackObject だが SubTasksDone もそうしては?? とのコメントも...)
((cite: hotspot/src/share/vm/utilities/workgroup.hpp))
// As above, but for sequential tasks, i.e. instead of claiming
// sub-tasks from a set (possibly an enumeration), claim sub-tasks
// in sequential order. This is ideal for claiming dynamically
// partitioned tasks (like striding in the parallel remembered
// set scanning). Note that unlike the above class this is
// a stack object - is there any reason for it not to be?
class SequentialSubTasksDone : public StackObj {
SubTasksDone::is_task_claimed() では取得したい処理を引数で指定できるが, SequentialSubTasksDone::is_task_claimed() では引数が参照渡しになっており, 逆に割り当てられた処理がこの引数経由で返される.
(処理は番号の小さいものから順に割り振られていく. 処理が全部割り振られてしまうと返値として true が返される.)
((cite: hotspot/src/share/vm/utilities/workgroup.hpp))
// Returns false if the next task in the sequence is unclaimed,
// and ensures that it is claimed. Will set t to be the index
// of the claimed task in the sequence. Will return true if
// the task cannot be claimed and there are none left to claim.
bool is_task_claimed(int& t);
See: here for details
並列 GC 処理で各 GC スレッドに割り当てられる ID を管理するクラス.
(?? 現状では G1GC の DirtyCardQueueSet 内でしか使われていない模様... #TODO)
((cite: hotspot/src/share/vm/utilities/workgroup.hpp))
// Represents a set of free small integer ids.
class FreeIdSet {
(現状では G1GC 専用のクラスである模様)
DirtyCardQueueSet オブジェクトの _free_ids フィールドに(のみ)格納されている.
(なお, ここに格納されているオブジェクトへのポインタは FreeIdSet クラスの _sets フィールドにも格納されている)
DirtyCardQueueSet::initialize() 内で(のみ)生成されている.
DirtyCardQueueSet::mut_process_buffer() 内で(のみ)使用されている.
内部では, 未使用の ID を線形リスト状にして管理している.
(このフリーリストは, ids フィールドの int 配列と _hd フィールドの int 値で構成される. _hd フィールドがフリーリストの先頭 index を保持しており, ids フィールドの配列要素はそれぞれリストの次の要素の index を格納している)
((cite: hotspot/src/share/vm/utilities/workgroup.hpp))
int* _ids;
int _hd;
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.