MMTk代码学习(系统结构与流程)

阅读更多

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
  • 内存管理初始化:
    1. enableAllocation 开启内存分配
    2. processOptions 参数处理
    3. enableCollection 开启垃圾收集,并spawning一个GC线程
    4. fullyBooted 完全初始化
  • 与MemoryManager互通的API
  • 管理具体步骤
    • Simple类

MutatorContext

  • 非同步GC(利用读写栅栏处理)
  • Initialization
  • Collection: collectionPhase
  • Allocation
    • checkAllocator 选择allocator
    • alloc 根据请求分配空间
    • postAlloc 分配成功,设置object-header
  • Space
  • 各种数据类型的读写栅栏

CollectorContext

  • 全局同步
  • allocCopy
  • postCopy
  • run 启动线程的流程:
    1. Plan::enableCollection() VM.collection.spawnCollectorContext(controlCollectorContext)
    2. CollectorContext::run()
    3. 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;
    }
}
 

 

你可能感兴趣的:(JVM,GC,MMTk)