MMTk的整体结构和驱动模型主要由Plan, CollectorContext, MutatorContext, Phase组成:
- Plan 全局模块,初始化用的主要接口
- CollectorContext 线程级内存分配接口,独立GC线程 收集?
- MutatorContext 全局内存分配 赋值?
Plan
- 基本常量管理
- 各种space初始化:
- immortal:ImmortalSpace 永生数据空间
- meta: RawPageSpace MMTk的元数据空间
- los: LargeObjectSpace 大对象数据空间
- sanity: RawPageSpace 支持Sanity-checker的数据空间
- non-moving: MarkSweepSpace
- small-code: MarkSweepSpace
- large-code: LargeObjectSpace
- 内存管理初始化:
- enableAllocation 开启内存分配
- processOptions 参数处理
- enableCollection 开启垃圾收集,并spawning一个GC线程
- fullyBooted 完全初始化
- 与MemoryManager互通的API
- 管理具体步骤
- Simple类
MutatorContext
- 非同步GC(利用读写栅栏处理)
- Initialization
- Collection: collectionPhase
- Allocation
- checkAllocator 选择allocator
- alloc 根据请求分配空间
- postAlloc 分配成功,设置object-header
- Space
- 各种数据类型的读写栅栏
CollectorContext
- 全局同步
- allocCopy
- postCopy
- run 启动线程的流程:
- Plan::enableCollection() VM.collection.spawnCollectorContext(controlCollectorContext)
- CollectorContext::run()
- Simple::run()
//ParallelCollector @Unpreemptible public void run() { while(true) { park(); collect(); } }
- rendezvous() 集中各个线程
Phase主要流程
/**
* Process the phase stack. This method is called by multiple threads.
*/
private static void processPhaseStack(boolean resume) {
/* Global and Collector instances used in phases */
Plan plan = VM.activePlan.global();
ParallelCollector collector = (ParallelCollector)VM.activePlan.collector();
int order = collector.rendezvous();
final boolean primary = order == 0;
boolean log = Options.verbose.getValue() >= 6;
boolean logDetails = Options.verbose.getValue() >= 7;
if (primary && resume) {
Plan.setGCStatus(Plan.GC_PROPER);
}
/* In order to reduce the need for synchronization, we keep an odd or even
* counter for the number of phases processed. As each phase has a single
* rendezvous it is only possible to be out by one so the odd or even counter
* protects us. */
boolean isEvenPhase = true;
if (primary) {
/* Only allow concurrent collection if we are not collecting due to resource exhaustion */
allowConcurrentPhase = Plan.isInternalTriggeredCollection() && !Plan.isEmergencyCollection();
/* First phase will be even, so we say we are odd here so that the next phase set is even*/
setNextPhase(false, getNextPhase(), false);
}
/* Make sure everyone sees the first phase */
collector.rendezvous();
/* The main phase execution loop */
int scheduledPhase;
while((scheduledPhase = getCurrentPhase(isEvenPhase)) > 0) {
short schedule = getSchedule(scheduledPhase);
short phaseId = getPhaseId(scheduledPhase);
Phase p = getPhase(phaseId);
/* Start the timer(s) */
if (primary) {
if (resume) {
resumeComplexTimers();
}
if (p.timer != null) p.timer.start();
if (startComplexTimer > 0) {
Phase.getPhase(startComplexTimer).timer.start();
startComplexTimer = 0;
}
}
if (log) {
Log.write("Execute ");
p.logPhase();
}
/* Execute a single simple scheduled phase */
switch (schedule) {
/* Global phase */
case SCHEDULE_GLOBAL: {
if (logDetails) Log.writeln(" as Global...");
if (primary) {
plan.collectionPhase(phaseId);
}
break;
}
/* Collector phase */
case SCHEDULE_COLLECTOR: {
if (logDetails) Log.writeln(" as Collector...");
collector.collectionPhase(phaseId, primary);
break;
}
/* Mutator phase */
case SCHEDULE_MUTATOR: {
if (logDetails) Log.writeln(" as Mutator...");
/* Iterate through all mutator contexts */
MutatorContext mutator;
while ((mutator = VM.activePlan.getNextMutator()) != null) {
mutator.collectionPhase(phaseId, primary);
}
break;
}
/* Concurrent phase */
case SCHEDULE_CONCURRENT: {
/* We are yielding to a concurrent collection phase */
if (logDetails) Log.writeln(" as Concurrent, yielding...");
if (primary) {
concurrentPhaseId = phaseId;
/* Concurrent phase, we need to stop gc */
Plan.setGCStatus(Plan.NOT_IN_GC);
Plan.controlCollectorContext.requestConcurrentCollection();
}
collector.rendezvous();
if (primary) {
pauseComplexTimers();
}
return;
}
default: {
/* getNextPhase has done the wrong thing */
VM.assertions.fail("Invalid schedule in Phase.processPhaseStack");
break;
}
}
if (primary) {
/* Set the next phase by processing the stack */
int next = getNextPhase();
boolean needsResetRendezvous = (next > 0) && (schedule == SCHEDULE_MUTATOR && getSchedule(next) == SCHEDULE_MUTATOR);
setNextPhase(isEvenPhase, next, needsResetRendezvous);
}
/* Sync point after execution of a phase */
collector.rendezvous();
/* Mutator phase reset */
if (primary && schedule == SCHEDULE_MUTATOR) {
VM.activePlan.resetMutatorIterator();
}
/* At this point, in the case of consecutive phases with mutator
* scheduling, we have to double-synchronize to ensure all
* collector threads see the reset mutator counter. */
if (needsMutatorResetRendezvous(isEvenPhase)) {
collector.rendezvous();
}
/* Stop the timer(s) */
if (primary) {
if (p.timer != null) p.timer.stop();
if (stopComplexTimer > 0) {
Phase.getPhase(stopComplexTimer).timer.stop();
stopComplexTimer = 0;
}
}
/* Flip the even / odd phase sense */
isEvenPhase = !isEvenPhase;
resume = false;
}
}