Top


定義場所(file name)

hotspot/src/share/vm/services/memoryManager.cpp

説明(description)

// A collector MUST, even if it does not complete for some reason,
// make a TraceMemoryManagerStats object where countCollection is true,
// to ensure the current gc stat is placed in _last_gc_stat.

名前(function name)

void GCMemoryManager::gc_end(bool recordPostGCUsage,
                             bool recordAccumulatedGCTime,
                             bool recordGCEndTime, bool countCollection,
                             GCCause::Cause cause) {

本体部(body)

  {- -------------------------------------------
  (1) (引数の recordAccumulatedGCTime が指定されていれば) GC 終了時の時刻を記録しておく.
      (See: sun.management.GarbageCollectorImpl.getCollectionTime())
      ---------------------------------------- -}

      if (recordAccumulatedGCTime) {
        _accumulated_timer.stop();
      }

  {- -------------------------------------------
  (1) (引数の recordGCBeginTime が指定されていれば) GC 終了時の時刻を記録しておく.
      (See: GCStatInfo)
      ---------------------------------------- -}

      if (recordGCEndTime) {
        _current_gc_stat->set_end_time(Management::timestamp());
      }

  {- -------------------------------------------
  (1) (引数の recordPostGCUsage が指定されていれば) 
      全ての MemoryPool に対して, GCStatInfo::set_after_gc_usage() で 
      GC 終了時の使用量を記録しておく.

      なお, (DTrace のフック点) でもある.

      また, (JMM のフック点) でもある.
      * 全ての MemoryPool に対して, LowMemoryDetector::detect_after_gc_memory() が呼び出される.
        (See: LowMemoryDetector)
      * もし GCNotifier の通知を行う必要があれば (= GCNotifier::is_notification_enabled() が true ならば)
        GCNotifier::pushNotification() が呼び出される.
        (See: GCNotifier)
      ---------------------------------------- -}

      if (recordPostGCUsage) {
        int i;
        // keep the last gc statistics for all memory pools
        for (i = 0; i < MemoryService::num_memory_pools(); i++) {
          MemoryPool* pool = MemoryService::get_memory_pool(i);
          MemoryUsage usage = pool->get_memory_usage();

          HS_DTRACE_PROBE8(hotspot, mem__pool__gc__end,
            name(), strlen(name()),
            pool->name(), strlen(pool->name()),
            usage.init_size(), usage.used(),
            usage.committed(), usage.max_size());

          _current_gc_stat->set_after_gc_usage(i, usage);
        }

        // Set last collection usage of the memory pools managed by this collector
        for (i = 0; i < num_memory_pools(); i++) {
          MemoryPool* pool = get_memory_pool(i);
          MemoryUsage usage = pool->get_memory_usage();

          // Compare with GC usage threshold
          pool->set_last_collection_usage(usage);
          LowMemoryDetector::detect_after_gc_memory(pool);
        }
        if(is_notification_enabled()) {
          bool isMajorGC = this == MemoryService::get_major_gc_manager();
          GCNotifier::pushNotification(this, isMajorGC ? "end of major GC" : "end of minor GC",
                                       GCCause::to_string(cause));
        }
      }

  {- -------------------------------------------
  (1) (引数の countCollection が指定されていれば) 
      GC 回数 (_num_collections フィールド) の値をインクリメントし, 
      _last_gc_stat フィールドと _current_gc_stat フィールドの値を入れ替えておく.
      (See: GCMemoryManager::get_last_gc_stat())
      ---------------------------------------- -}

      if (countCollection) {
        _num_collections++;
        // alternately update two objects making one public when complete
        {
          MutexLockerEx ml(_last_gc_lock, Mutex::_no_safepoint_check_flag);
          GCStatInfo *tmp = _last_gc_stat;
          _last_gc_stat = _current_gc_stat;
          _current_gc_stat = tmp;
          // reset the current stat for diagnosability purposes
          _current_gc_stat->clear();
        }
      }
    }

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.