JVM垃圾回收

根据《JVM垃圾回收》我们对垃圾收集器有个初步的概念.

相关模块介绍


//VM_Operation
//	VM_GC_Operation #是所有执行垃圾回收的VM_Operation的基类
//		VM_CollectForAllocation #与其子类都是内存分配失败触发垃圾回收,然后尝试分配内存的操作
//			VM_GenCollectForAllocation

//表示一类在JVM线程中执行的操作,类似java中的任务
//hotspot/src/share/vm/runtime/vm_operations.hpp
class VM_Operation: public CHeapObj<mtInternal> {

  enum Mode {
    _safepoint,       //表示执行此操作需要加锁+安全点
    _no_safepoint,    //表示执行此操作需要加锁
    _concurrent,      //无需要任务条件
    _async_safepoint  //表示执行此操作需要安全点
  };
  
  //具体执行VM_Operation的方法,通过evaluate方法调用,子类不能改写evaluate方法的实现
  doit:
  //用于执行准备工作,当Java线程调用VMThread::execute((VM_Operation*)执行某个VM_Operation时会先执行doit_prologue如果该方法返回true才会执行evaluate方法,否则被取消不执行。
  doit_prologue
  //用于执行某些依赖于VM_Operation执行结果的动作,当VM_Operation执行完成,Java线程会调用doit_epilogue方法一次。
  doit_epilogue
}

//表示一个特殊的专门用来执行比较耗时的VM_Operation的原生线程
//hotspot/src/share/vm/runtime/vMThread.hpp
class VMThread {
    
    //当前执行的VM operation
    static VM_Operation*     _cur_vm_operation;   
    // 缓存待执行的VM operation 队列
    static VMOperationQueue* _vm_queue;   
    
    
    void VMThread::create() {
       //创建VMThread线程,及VMOperationQueue队列
    }
    
	void VMThread::execute(VM_Operation* op) {
	  //用于执行某个VM_Operation,execute方法会先执行doit_prologue,该方法执行成功后将该操作放入一个等待队列中,然后等待VMThread执行该操作完成,最后再执行doit_epilogue
	}
	 
    void VMThread::run() {
        //其中loop方法执行的核心业务逻辑了,该方法不断从待执行的VM Operation队列_vm_queue中获取待执行的VM_Operation实例,然后调用其evaluate方法
    }
}
//描述分代参数的一个类
//hotspot/src/share/vm/memory/generationSpec.hpp
class GenerationSpec : public CHeapObj<mtGC> {
  Generation::Name _name;//分代名
  size_t           _init_size;//初始大步
  size_t           _max_size;//最大大小

  // 返回这个分代所需要的 remembered set 空间.
  virtual int n_covered_regions() const { return 1; }
  
  //创建分带代
  Generation* GenerationSpec::init(ReservedSpace rs, int level,
	                                 GenRemSet* remset) {
	  switch (name()) {
	    case Generation::DefNew:
	      return new DefNewGeneration(rs, init_size(), level);
	    case Generation::MarkSweepCompact:
	      return new TenuredGeneration(rs, init_size(), level, remset);	
	    case Generation::ParNew:
	      return new ParNewGeneration(rs, init_size(), level);
	    case Generation::ASParNew:
	      return new ASParNewGeneration(rs,init_size(),init_size() ,level);	
	    case Generation::ConcurrentMarkSweep: {
	      assert(UseConcMarkSweepGC, "UseConcMarkSweepGC should be set");
	      CardTableRS* ctrs = remset->as_CardTableRS();
	      if (ctrs == NULL) {
	        vm_exit_during_initialization("Rem set incompatibility.");
	      }
	      // Otherwise
	      // The constructor creates the CMSCollector if needed,
	      // else registers with an existing CMSCollector
	      ConcurrentMarkSweepGeneration* g = NULL;
	      g = new ConcurrentMarkSweepGeneration(rs,
	                 init_size(), level, ctrs, UseCMSAdaptiveFreeLists,
	                 (FreeBlockDictionary<FreeChunk>::DictionaryChoice)CMSDictionaryChoice);
	
	      g->initialize_performance_counters();
	
	      return g;
	    }
	    case Generation::ASConcurrentMarkSweep: {
	       //...
	    }	
	    default:
	      guarantee(false, "unrecognized GenerationName");
	      return NULL;
	  }
	}  
}

//用来记录不同分代年龄的对象的大小,然后据此动态调整tenuring_threshold
//hotspot/src/share/vm/gc_implementation/shared/ageTable.hpp
class ageTable  {
  
  enum { table_size = markOopDesc::max_age + 1 };
  //sizes就是保存不同分代年龄的对象的大小的数组
  size_t sizes[table_size];

  //所对象存进行
  //如果想取1岁对象占分代的大小,就直接sizes[1]
  void add(oop p, size_t oop_size) {
    add(p->age(), oop_size);
  }
 
 void add(uint age, size_t oop_size) {
	sizes[age] += oop_size;
 }
 
 //传一个的survivor_capacity值,根据ageTable的数据,把对象重新画区
 uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) 

}

//Space及其子类是Generation中用于内存分配管理的底层实现
//hotspot/src/share/vm/memory/space.hpp
class Space: public CHeapObj<mtGC> {
  //内存区域的起始地址
  HeapWord* _bottom;
  //内存区域的终止地址
  HeapWord* _end;

  // 用来遍历Space内的MemRegion
  MemRegionClosure* _preconsumptionDirtyCardClosure;
}

//增加了压缩操作的支持,即在垃圾回收后通过复制移动Java对象的位置减少Space内部的内存空洞和碎片问题,提升内存利用率
//hotspot/src/share/vm/memory/space.hpp
class CompactibleSpace: public Space {
}

//表示一个空闲内存空间是地址连续的Space,从而支持快速的内存分配和压缩
//hotspot/src/share/vm/memory/space.hpp
class ContiguousSpace: public CompactibleSpace {
  //bottom到top之间的内存都是已经被分配出去的内存
  HeapWord* _top;
  //从bottom到_concurrent_iteration_safe_limit之间的对象都被认为是已经初始化完成的对象,对于object_iterate_careful方法可以安全遍历的,该属性在初始化时通常设置为bottom,在compact结束后设置为compact_top。
  HeapWord* _concurrent_iteration_safe_limit;
  //负责对Space执行mangle的辅助类
  GenSpaceMangler* _mangler;
}

//用来表示Eden区
class EdenSpace : public ContiguousSpace {
  //关联的年轻代DefNewGeneration实例
  DefNewGeneration* _gen;
  //分配内存的一个软限制, 当达到了这个限制后,慢速分配的代码可以执行其他的逻辑,然后调整_soft_end到一个新的限制或者end()
  HeapWord* _soft_end;
}

// CollectedHeap
//   SharedHeap 分层的堆基类
//     GenCollectedHeap 普通分带法
//     G1CollectedHeap  G1分带法
//   ParallelScavengeHeap ps分带及策略
//一个抽象类,表示一个Java堆,定义了各种垃圾回收算法必须实现的公共接口,这些接口就是上层类用来分配Java对象,分配TLAB,获取Java堆使用情况等的统一API
//hotspot/src/share/vm/gc_interface/collectedHeap.hpp
class CollectedHeap : public CHeapObj<mtInternal> {
	
  //填充数组的最大值	
  static size_t _filler_array_max_size;
  //用来打印GC日志
  GCHeapLog* _gc_heap_log;
  //开启C2编译时使用,支持ReduceInitialCardMarks
  bool _defer_initial_card_mark;
  //Java堆对应的一段连续内存空间
  MemRegion _reserved;
  //卡表(CardTable)的基类
  //BarrierSet的功能类似于一个拦截器,在读写动作实际作用于内存前执行某些前置或者后置动作
  BarrierSet* _barrier_set;
  //是否正在执行GC
  bool _is_gc_active;
  //并行执行GC任务的线程数
  uint _n_par_threads;
  //从JVM启动至今的GC次数
  unsigned int _total_collections;
  //从JVM启动至今的Full GC次数
  unsigned int _total_full_collections;
  //当前GC被触发的原因,Cause是GCCause定义的枚举
  GCCause::Cause _gc_cause;
  //上一次GC被触发的原因
  GCCause::Cause _gc_lastcause;
  //开启UsePerfData时用来保存_gc_cause
  PerfStringVariable* _perf_gc_cause;
  //开启UsePerfData时用来保存_gc_lastcause
  PerfStringVariable* _perf_gc_lastcause;
}

//hotspot/src/share/vm/memory/sharedHeap.hpp
class SharedHeap : public CollectedHeap {
  //静态SharedHeap实例,单例
  static SharedHeap* _sh;
  // the Gen Remembered Set,卡表实现
  GenRemSet* _rem_set;
  //垃圾回收策略
  CollectorPolicy *_collector_policy;
  //遍历Java线程包含的oop使用的
  int _strong_roots_parity;
  //执行并行GC(parallel GC)的线程池
  FlexibleWorkGang* _workers;

  //SharedHeap构造
  SharedHeap::SharedHeap(CollectorPolicy* policy_) :
	  CollectedHeap(),
	  _collector_policy(policy_),
	  _rem_set(NULL),
	  _strong_roots_parity(0),
	  _workers(NULL)
	{
	  //初始化静态属性_sh
	  _sh = this;  // ch is static, should be set only once.
	  if ((UseParNewGC ||
	      (UseConcMarkSweepGC && (CMSParallelInitialMarkEnabled ||
	                              CMSParallelRemarkEnabled)) ||
	       UseG1GC) &&
	      ParallelGCThreads > 0) {
	    //初始化执行并行GC的线程池  
	    _workers = new FlexibleWorkGang("Parallel GC Threads", ParallelGCThreads,
	                            /* are_GC_task_threads */true,
	                            /* are_ConcurrentGC_threads */false);
	    if (_workers == NULL) {
	      vm_exit_during_initialization("Failed necessary allocation.");
	    } else {
	      _workers->initialize_workers();
	    }
	  }
	}

}

//heap具体的分带实现
//hotspot/src/share/vm/memory/genCollectedHeap.hpp
class GenCollectedHeap : public SharedHeap {
  //静态GenCollectedHeap实例,单例
  static GenCollectedHeap* _gch;
  //包含的Generation的个数,通常是2(老年代,年轻带)
  int _n_gens;
  //Generation数组,分代的具体指针
  Generation* _gens[max_gens];
  //GenerationSpec主要用来存储各分带的创建数据
  GenerationSpec** _gen_specs;
  //垃圾回收策略
  GenCollectorPolicy* _gen_policy;
  //执行promote是否会失败
  bool _incremental_collection_failed;
  //已经执行万恒的Full GC的次数
  unsigned int _full_collections_completed;
  //用于控制根节点遍历任务的并行执行
  SubTasksDone* _process_strong_tasks;

  //GenCollectedHeap构造
  GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy) :
	  SharedHeap(policy),
	  _gen_policy(policy),
	  _process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)),
	  _full_collections_completed(0)
	{
	  assert(policy != NULL, "Sanity check");
	}
  
	jint GenCollectedHeap::initialize() {
	  CollectedHeap::pre_initialize();
	 
	  int i;
	  //_n_gens表示有多少代,通常是2代,年轻代和老年代
	  _n_gens = gen_policy()->number_of_generations();
	 
	  guarantee(HeapWordSize == wordSize, "HeapWordSize must equal wordSize");
	 
	  size_t gen_alignment = Generation::GenGrain;
	  //拿出堆模型数据
	  _gen_specs = gen_policy()->generations();
	  for (i = 0; i < _n_gens; i++) {
	    //将内存的初始值和最大值按照内存分配粒度对齐
	    _gen_specs[i]->align(gen_alignment);
	  }
	 
	  char* heap_address;
	  size_t total_reserved = 0;
	  int n_covered_regions = 0;
	  ReservedSpace heap_rs;
	 
	  size_t heap_alignment = collector_policy()->heap_alignment();
	  //根据各GenerationSpec的最大大小计算总的需要保留的内存空间,然后申请指定大小的连续内存空间
	  heap_address = allocate(heap_alignment, &total_reserved,
	                          &n_covered_regions, &heap_rs);
	 
	  if (!heap_rs.is_reserved()) {
	    //申请失败
	    vm_shutdown_during_initialization(
	      "Could not reserve enough space for object heap");
	    return JNI_ENOMEM;
	  }
	 
	  //设置_reserved相关属性
	  _reserved = MemRegion((HeapWord*)heap_rs.base(),
	                        (HeapWord*)(heap_rs.base() + heap_rs.size()));
	  _reserved.set_word_size(0);
	  _reserved.set_start((HeapWord*)heap_rs.base());
	  size_t actual_heap_size = heap_rs.size();
	  _reserved.set_end((HeapWord*)(heap_rs.base() + actual_heap_size));
	 
	  //collector_policy()和gen_policy()表示相同变量
	  //根据各区域名需要的_rem_set区域,初始化GenRemSet
	  _rem_set = collector_policy()->create_rem_set(_reserved, n_covered_regions);
	  set_barrier_set(rem_set()->bs());
	 
	  _gch = this;
	  
	  //初始化各Generation
	  for (i = 0; i < _n_gens; i++) {
	    //提取出max_size的内存
	    ReservedSpace this_rs = heap_rs.first_part(_gen_specs[i]->max_size(), false, false);
	    //使用提取出的,内存和卡表引出,创建初始化分代
	    _gens[i] = _gen_specs[i]->init(this_rs, i, rem_set());
	    //将下次内存指针向下移max_size
	    heap_rs = heap_rs.last_part(_gen_specs[i]->max_size());
	  }
	 
	  //将_incremental_collection_failed置为false
	  clear_incremental_collection_failed();
	 
	#if INCLUDE_ALL_GCS
	  if (collector_policy()->is_concurrent_mark_sweep_policy()) {
	    //如果是CMS则创建CMSCollector
	    bool success = create_cms_collector();
	    if (!success) return JNI_ENOMEM;
	  }
	#endif // INCLUDE_ALL_GCS
	 
	  return JNI_OK;
	}
	
	char* GenCollectedHeap::allocate(size_t alignment,
	                                 size_t* _total_reserved,
	                                 int* _n_covered_regions,
	                                 ReservedSpace* heap_rs){
	  const char overflow_msg[] = "The size of the object heap + VM data exceeds "
	    "the maximum representable size";
	 
	  // Now figure out the total size.
	  size_t total_reserved = 0;
	  int n_covered_regions = 0;
	  const size_t pageSize = UseLargePages ?
	      os::large_page_size() : os::vm_page_size();
	 
	  assert(alignment % pageSize == 0, "Must be");
	  
	  //遍历所有的_gen_specs,累加各GenerationSpec的max_size和n_covered_regions
	  for (int i = 0; i < _n_gens; i++) {
	    total_reserved += _gen_specs[i]->max_size();
	    if (total_reserved < _gen_specs[i]->max_size()) {
	      vm_exit_during_initialization(overflow_msg);
	    }
	    n_covered_regions += _gen_specs[i]->n_covered_regions();
	  }
	  //校验累加后的total_reserved已经是内存对齐的
	  assert(total_reserved % alignment == 0,
	         err_msg("Gen size; total_reserved=" SIZE_FORMAT ", alignment="
	                 SIZE_FORMAT, total_reserved, alignment));
	 
	  //加2是为卡表保留的
	  n_covered_regions += 2;
	  
	  //赋值
	  *_total_reserved = total_reserved;
	  *_n_covered_regions = n_covered_regions;
	  //申请指定大小的连续内存空间
	  *heap_rs = Universe::reserve_heap(total_reserved, alignment);
	  //返回基地址
	  return heap_rs->base();
	}

    //执行垃圾回收的核心方法,其底层核心就是各Genaration的collect方法
	void GenCollectedHeap::do_collection(bool  full,
	                                     bool   clear_all_soft_refs,
	                                     size_t size,
	                                     bool   is_tlab,
	                                     int    max_level) {
	  bool prepared_for_verification = false;
	  ResourceMark rm;
	  	  
	  //校验处于安全点上
	  assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
	  //校验调用线程是VMThread 或者CMS Thread
	  assert(my_thread->is_VM_thread() ||
	         my_thread->is_ConcurrentGC_thread(),
	         "incorrect thread type capability");
	  //校验获取了Heap_lock锁
	  assert(Heap_lock->is_locked(),
	         "the requesting thread should have the Heap_lock");
	  guarantee(!is_gc_active(), "collection is not reentrant");
	  assert(max_level < n_gens(), "sanity check");
	 
	  //检查是否有线程处于JNI关键区,check_active_before_gc返回true表示有,则终止当前GC,等待线程退出
	  //最后一个退出的线程会负责执行GC
	  if (GC_locker::check_active_before_gc()) {
	    return; 
	  }
	 
	  //是否需要清除软引用
	  const bool do_clear_all_soft_refs = clear_all_soft_refs ||
	                          collector_policy()->should_clear_all_soft_refs();
	  
	  //ClearedAllSoftRefs通过析构函数设置CollectorPolicy的_all_soft_refs_clear属性
	  ClearedAllSoftRefs casr(do_clear_all_soft_refs, collector_policy());
	  
	  //获取元空间已使用内存
	  const size_t metadata_prev_used = MetaspaceAux::used_bytes();
	  //打印GC的堆内存使用情况
	  print_heap_before_gc();
	 
	  {
	    //临时设置_is_gc_active为true,表示GC开始了
	    FlagSetting fl(_is_gc_active, true);
	 
	    bool complete = full && (max_level == (n_gens()-1));
	    const char* gc_cause_prefix = complete ? "Full GC" : "GC";
	    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
	    GCTraceTime t(GCCauseString(gc_cause_prefix, gc_cause()), PrintGCDetails, false, NULL, GCId::peek());
	    
	    //遍历各Generation执行GC准备工作
	    gc_prologue(complete);
	    //增加GC次数
	    increment_total_collections(complete);
	    //统计总的内存使用量
	    size_t gch_prev_used = used();
	 
	    int starting_level = 0;
	    
	    if (full) {
	      //如果老年代设置了full Gc要先收集年轻代的话
	      //full_collects_younger_generations = false
	      //否则为true,starting_level=1
	      for (int i = max_level; i >= 0; i--) {
	        if (_gens[i]->full_collects_younger_generations()) {
	          starting_level = i;
	          break;
	        }
	      }
	    }
	 
	    bool must_restore_marks_for_biased_locking = false;
	 
	    int max_level_collected = starting_level;
	    for (int i = starting_level; i <= max_level; i++) {
	      if (_gens[i]->should_collect(full, size, is_tlab)) {
	        //如果需要垃圾回收
	        if (i == n_gens() - 1) {  // a major collection is to happen
	          //如果是老年代
	          if (!complete) {
	            //increment_total_collections方法只有在complete为true时才会增加_total_full_collections计数
	            //此处complete为false,但还是老年代的GC,所以增加计数
	            increment_total_full_collections();
	          }
	          //根据参数配置dump
	          pre_full_gc_dump(NULL);    // do any pre full gc dumps
	        }
	    
	        GCTraceTime t1(_gens[i]->short_name(), PrintGCDetails, false, NULL, GCId::peek());
	        TraceCollectorStats tcs(_gens[i]->counters());
	        TraceMemoryManagerStats tmms(_gens[i]->kind(),gc_cause());
	 
	        size_t prev_used = _gens[i]->used();
	        //增加计数
	        _gens[i]->stat_record()->invocations++;
	        _gens[i]->stat_record()->accumulated_time.start();
	 
	        //记录各Generation的Space的top指针,生产版本为空实现
	        record_gen_tops_before_GC();
	 
	        if (PrintGC && Verbose) {
	          gclog_or_tty->print("level=%d invoke=%d size=" SIZE_FORMAT,
	                     i,
	                     _gens[i]->stat_record()->invocations,
	                     size*HeapWordSize);
	        }
	 
	        if (VerifyBeforeGC && i >= VerifyGCLevel &&
	            total_collections() >= VerifyGCStartAt) {
	          HandleMark hm;  // Discard invalid handles created during verification
	          if (!prepared_for_verification) {
	            prepare_for_verify();
	            prepared_for_verification = true;
	          }
	          Universe::verify(" VerifyBeforeGC:");
	        }
	        COMPILER2_PRESENT(DerivedPointerTable::clear());
	 
	        if (!must_restore_marks_for_biased_locking &&
	           //DefNewGeneration返回false,ConcurrentMarkSweepGeneration采用父类默认实现返回true
	            _gens[i]->performs_in_place_marking()) {
	          must_restore_marks_for_biased_locking = true;
	          //将各线程的持有偏向锁的oop的对象头保存起来
	          BiasedLocking::preserve_marks();
	        }
	 
	        // Do collection work
	        {
	          
	          HandleMark hm;  // Discard invalid handles created during gc
	          save_marks();   // save marks for all gens
	          
	          ReferenceProcessor* rp = _gens[i]->ref_processor();
	         
	          if (rp->discovery_is_atomic()) {
	            rp->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/);
	            rp->setup_policy(do_clear_all_soft_refs);
	          } else {
	            //collect方法会调用enable_discovery方法
	          }
	          //执行垃圾回收
	          _gens[i]->collect(full, do_clear_all_soft_refs, size, is_tlab);
	          if (!rp->enqueuing_is_done()) {
	            //enqueuing_is_done为false
	            //将处理后剩余的References实例加入到pending-list中
	            rp->enqueue_discovered_references();
	          } else {
	            //enqueuing_is_done为true,已经加入到pending-list中了,将其恢复成默认值
	            rp->set_enqueuing_is_done(false);
	          }
	          rp->verify_no_references_recorded();
	        }
	        max_level_collected = i;
	 
	        // Determine if allocation request was met.
	        if (size > 0) {
	          if (!is_tlab || _gens[i]->supports_tlab_allocation()) {
	            if (size*HeapWordSize <= _gens[i]->unsafe_max_alloc_nogc()) {
	              size = 0;
	            }
	          }
	        }
	 
	        COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
	  
	        _gens[i]->stat_record()->accumulated_time.stop();
	        //更新各Generation的GC统计信息
	        update_gc_stats(i, full);
	 
	        if (VerifyAfterGC && i >= VerifyGCLevel &&
	            total_collections() >= VerifyGCStartAt) {
	          HandleMark hm;  // Discard invalid handles created during verification
	          Universe::verify(" VerifyAfterGC:");
	        }
	 
	        if (PrintGCDetails) {
	          gclog_or_tty->print(":");
	          _gens[i]->print_heap_change(prev_used);
	        }
	      }
	    }//for循环结束
	 
	    //是否Full GC
	    complete = complete || (max_level_collected == n_gens() - 1);
	 
	    if (complete) { // We did a "major" collection
	      //根据配置dump
	      post_full_gc_dump(NULL);   // do any post full gc dumps
	    }
	 
	    if (PrintGCDetails) {
	      print_heap_change(gch_prev_used);
	 
	      if (complete) {
	        MetaspaceAux::print_metaspace_change(metadata_prev_used);
	      }
	    }
	 
	    for (int j = max_level_collected; j >= 0; j -= 1) {
	      //调整各Generation的容量
	      _gens[j]->compute_new_size();
	    }
	 
	    if (complete) {
	      //删掉被卸载的ClassLoader实例及其相关元数据
	      ClassLoaderDataGraph::purge();
	      MetaspaceAux::verify_metrics();
	      //重置元空间大小
	      MetaspaceGC::compute_new_size();
	      update_full_collections_completed();
	    }
	 
	    //跟踪GC后的内存使用
	    MemoryService::track_memory_usage();
	 
	    gc_epilogue(complete);
	 
	    if (must_restore_marks_for_biased_locking) {
	      BiasedLocking::restore_marks();
	    }
	  }
	 
	  AdaptiveSizePolicy* sp = gen_policy()->size_policy();
	  AdaptiveSizePolicyOutput(sp, total_collections());
	 
	  print_heap_after_gc();
	 
	}

	//DefNewGeneration采用父类Generation的默认实现,返回false
	//ConcurrentMarkSweepGeneration的实现如下
	//UseCMSCompactAtFullCollection默认为true,表示FullGC时所使用Mark-Sweep-Compact算法
	//CollectGen0First默认为false,表示是否在FullGC前收集年轻代
	virtual bool full_collects_younger_generations() const {
	    return UseCMSCompactAtFullCollection && !CollectGen0First;
	  }


}

// Generation
//   CardGeneration 
//     ConcurrentMarkSweep #cms
//     	  ASConcurrentMarkSweep # 自适应cms
//     OneContigSpaceCardGeneration  
//     	  TenuredGeneration 
//   DefNewGeneration
//     ParNewGeneration
//     	  ASParNewGeneration 
//CMS算法使用的表示年轻代的DefNewGeneration和表示支持自适应调整堆内存大小的老年代的ASConcurrentMarkSweepGeneration类
//表示分代内存中的一个“代”对应的内存区域,是各种分代内存实现的抽象类
//hotspot/src/share/vm/memory/generation.hpp
class Generation: public CHeapObj<mtGC> {
  //记录上一次GC的发生时间
  jlong _time_of_last_gc; 
  //在GC过程中的某个特殊时点使用的,用于记录某个值
  MemRegion _prev_used_region; 
  //为当前Generation保留的一段连续的内存地址空间,注意不能跟其他的Generation的地址空间有交叉
  MemRegion _reserved;
  // Memory area reserved for generation
  VirtualSpace _virtual_space;
  //当前Generation在类继承关系中的级别
  int _level;
  //用于处理Reference实例的处理器
  ReferenceProcessor* _ref_processor;
  //用于GC性能跟踪
  CollectorCounters* _gc_counters;
  //收集GC的统计数据
  GCStats* _gc_stats;

  //Generation定义了一个枚举Name来描述各子类,其定义如下:
  enum Name {
    ASParNew,
    ASConcurrentMarkSweep,
    DefNew,
    ParNew,
    MarkSweepCompact,(对应继承类TenuredGeneration)
    ConcurrentMarkSweep,
    Other
  };

  //默认种类返回
  virtual Generation::Name kind() { return Generation::Other;}
   
  //是否要收集
  //如果full为true,强制收集
  //否则判断空间是否充足 
  virtual bool should_collect(bool   full,
                              size_t word_size,
                              bool   is_tlab) {
    return (full || should_allocate(word_size, is_tlab));
  } 
}

//表示一个使用卡表来标记对象修改
//hotspot/src/share/vm/memory/generation.hpp
class CardGeneration: public Generation {
 
  //与其他Generation实例共享的卡表实现实例(指向SharedHeap中的)
  GenRemSet* _rs;
  //当前Generation独享的BlockOffsetArray实现
  //记录内存块的起始位置
  BlockOffsetSharedArray* _bts;
  //老年代内存缩容的百分比,第一次是0,第二次是10,第三次是40,第四次是100,中间有一次扩容了则被重置为0,重新开始累加,避免频繁的缩容与扩容。
  size_t _shrink_factor;
  //老年代内存扩展或者缩容时的最低内存值 
  size_t _min_heap_delta_bytes;
  //GC开始时的内存容量
  size_t _capacity_at_prologue;
  //GC开始时的内存使用量
  size_t _used_at_prologue;
}

//表示CMS的老年代
//hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
class ConcurrentMarkSweepGeneration: public CardGeneration {
  //封装了老年代垃圾回收的相关属性和实现逻辑
  static CMSCollector*       _collector; 
  //老年代对应的Space实现
  CompactibleFreeListSpace*  _cmsSpace;   
  //直接从老年代分配而非promote时间接分配的内存的大小,是一个累加值,CMSStats使用的
  size_t _direct_allocated_words;
  //是否增量收集失败
  bool _incremental_collection_failed;
  //实际是一个CMSParGCThreadState指针数组,元素个数就是ParallelGCThreads,即并行GC的线程数,CMSParGCThreadState是执行老年代promote时使用的
  CMSParGCThreadState** _par_gc_thread_states;
  //老年代扩展的原因,shouldConcurrentCollect()方法据此判断是否应该GC
  CMSExpansionCause::Cause _expansion_cause;
  //是否完成压缩
  bool _did_compact;
  //触发老年代GC的内存占用百分比,是一个两位的小数 
  double _initiating_occupancy;


  //UseCMSCompactAtFullCollection默认为true,表示FullGC时所使用Mark-Sweep-Compact算法
 //CollectGen0First默认为false,表示是否在FullGC前收集年轻代
 virtual bool full_collects_younger_generations() const {
	    return UseCMSCompactAtFullCollection && !CollectGen0First;
	  }
}

//表示年轻代,包括(den, from- and to-space.)
//hotspot/src/share/vm/memory/defNewGeneration.hpp
class DefNewGeneration: public Generation {
  //对老年代的引用,初始化时为null,第一次GC时会赋值
  Generation* _next_gen;
  //将对象拷贝到老年代的分代年龄阈值,大于该值拷贝到老年代,否则拷贝到to区,该值在初始化时赋值成参数MaxTenuringThreshold,默认是15;每次GC结束后都会通过ageTable调整。
  uint        _tenuring_threshold;   
  //记录不同分代年龄的对象的总大小
  ageTable    _age_table;
  //表示年轻代中允许分配的对象的最大字宽数,默认是0,即无限制
  size_t      _pretenure_size_threshold_words;

  //真实地址大内存在ReservedSpace已经外面
  //用EdenSpace与ContiguousSpace等类,标识已计算出给年代代的东西
  //barrier_set也得新高监听区域
  DefNewGeneration::DefNewGeneration(ReservedSpace rs,
	                                   size_t initial_size,
	                                   int level,
	                                   const char* policy)
	  : Generation(rs, initial_size, level),
	    _promo_failure_drain_in_progress(false),
	    _should_allocate_from_space(false)
	{
	  MemRegion cmr((HeapWord*)_virtual_space.low(),
	                (HeapWord*)_virtual_space.high());
	  //重置bs对应的内存区域
	  Universe::heap()->barrier_set()->resize_covered_region(cmr);
	  //has_soft_ended_eden方法的返回值取决于属性CMSIncrementalMode,默认为false
	  //初始化三个内存区域
	  if (GenCollectedHeap::heap()->collector_policy()->has_soft_ended_eden()) {
	    _eden_space = new ConcEdenSpace(this);
	  } else {
	    _eden_space = new EdenSpace(this);
	  }
	  _from_space = new ContiguousSpace();
	  _to_space   = new ContiguousSpace();
	 
	  if (_eden_space == NULL || _from_space == NULL || _to_space == NULL)
	    vm_exit_during_initialization("Could not allocate a new gen space");
	 
	  //计算survivor区和eden区的最大空间,即年轻代最大内存时survivor区和eden区的内存空间
	  uintx alignment = GenCollectedHeap::heap()->collector_policy()->space_alignment();
	  uintx size = _virtual_space.reserved_size();
	  _max_survivor_size = compute_survivor_size(size, alignment);
	  _max_eden_size = size - (2*_max_survivor_size);
	 
	  //计算三个内存区的大小和边界,并初始化
	  compute_space_boundaries(0, SpaceDecorator::Clear, SpaceDecorator::Mangle);
	   //...
	}

   
  HeapWord* DefNewGeneration::allocate(size_t word_size,
	                                     bool is_tlab) {
	  //正常情况下只有慢速分配对象时才会进入此方法,此时在GenCollectHeap层已经获取了锁                                   
	  //par_allocate不要求调用方获取全局锁,底层使用cmpxchg原子指令,更快
	  HeapWord* result = eden()->par_allocate(word_size);
	  if (result != NULL) {
	    //如果分配成功
	    //CMSEdenChunksRecordAlways表示是否记录eden区分配的内存块,默认为true
	    if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
	      _next_gen->sample_eden_chunk();
	    }
	    return result;
	  }
	  do {
	    HeapWord* old_limit = eden()->soft_end();
	    if (old_limit < eden()->end()) {
	      //通知老年代,年轻代已经达到了分配限制soft_end,老年代会返回一个新的限制
	      //非iCMS模式下,该方法就是返回NULL,就end和soft_end一直
	      HeapWord* new_limit =
	        next_gen()->allocation_limit_reached(eden(), eden()->top(), word_size);
	      if (new_limit != NULL) {
	        //原子的修改eden区的soft_end属性
	        Atomic::cmpxchg_ptr(new_limit, eden()->soft_end_addr(), old_limit);
	      } else {
	        assert(eden()->soft_end() == eden()->end(),
	               "invalid state after allocation_limit_reached returned null");
	      }
	    } else {
	      //soft_end跟end一致了,必须扩容才能继续分配,终止循环
	      assert(old_limit == eden()->end(), "sanity check");
	      break;
	    }
	    //再次尝试分配,直到分配成功或者soft_end跟end一致
	    result = eden()->par_allocate(word_size);
	  } while (result == NULL);
	 
	  if (result == NULL) {
	    //从from区域分配内存
	    result = allocate_from_space(word_size);
	  } else if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
	    //while循环重试分配成功
	    _next_gen->sample_eden_chunk();
	  }
	  return result;
	} 
	//此方法的四个参数只有clear_all_soft_refs是有用的参数,如果为true表示会清除所有的软引用
	//如果是false则按照默认逻辑处理
	void DefNewGeneration::collect(bool   full,
	                               bool   clear_all_soft_refs,
	                               size_t size,
	                               bool   is_tlab) {
	  assert(full || size > 0, "otherwise we don't want to collect");
	 
	  GenCollectedHeap* gch = GenCollectedHeap::heap();
	  
	  //记录GC的开始时间和原因
	  //...
	 
	  //老年代
	  _next_gen = gch->next_gen(this);
	 
	  //判断老年代是否有足够的空间保存年轻代复制过去的对象
	  if (!collection_attempt_is_safe()) {
	    //通知GCH老年代空间不足
	    gch->set_incremental_collection_failed(); // Slight lie: we did not even attempt one
	    //老年代空间不足,终止年轻代的GC
	    return;
	  }
	  assert(to()->is_empty(), "Else not collection_attempt_is_safe");
	  
	  //将_promotion_failed属性置为false,记录promote失败信息的PromotionFailedInfo重置成初始状态
	  init_assuming_no_promotion_failure();
	 
	  GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL, gc_tracer.gc_id());
	  // Capture heap used before collection (for printing).
	  size_t gch_prev_used = gch->used();
	  
	  //设置GC Tracer
	  gch->trace_heap_before_gc(&gc_tracer);
	 
	  SpecializationStats::clear();
	 
	  //初始化两个遍历器
	  IsAliveClosure is_alive(this);
	  ScanWeakRefClosure scan_weak_ref(this);
	  
	  //重置ageTable
	  age_table()->clear();
	  //重置to区
	  to()->clear(SpaceDecorator::Mangle);
	  //重置cur_youngergen_card_val,并行遍历脏的卡表项时使用
	  gch->rem_set()->prepare_for_younger_refs_iterate(false);
	 
	  assert(gch->no_allocs_since_save_marks(0),
	         "save marks have not been newly set.");
	 
	  CollectorPolicy* cp = gch->collector_policy();
	  
	  //FastScanClosure用来遍历年轻代中的存活对象oop,第二个参数为true,表示会将oop对应的卡表项置为youngergen_card
	  FastScanClosure fsc_with_no_gc_barrier(this, false);
	  FastScanClosure fsc_with_gc_barrier(this, true);
	  
	  //KlassScanClosure用来遍历在上一次GC到当前GC之间创建的新的Klass对应的Class实例
	  KlassScanClosure klass_scan_closure(&fsc_with_no_gc_barrier,
	                                      gch->rem_set()->klass_rem_set());
	  //CLDToKlassAndOopClosure用来遍历一个ClassLoader加载的所有类对应的Class实例和依赖等                                    
	  CLDToKlassAndOopClosure cld_scan_closure(&klass_scan_closure,
	                                           &fsc_with_no_gc_barrier,
	                                           false);
	  //设置promote失败时的遍历器
	  set_promo_failure_scan_stack_closure(&fsc_with_no_gc_barrier);
	  //FastEvacuateFollowersClosure主要用来遍历被promote到老年代的对象,恢复其对象头并遍历其引用类型属性
	  FastEvacuateFollowersClosure evacuate_followers(gch, _level, this,
	                                                  &fsc_with_no_gc_barrier,
	                                                  &fsc_with_gc_barrier);
	 
	  assert(gch->no_allocs_since_save_marks(0),
	         "save marks have not been newly set.");
	  
	  //执行根节点遍历以及老年代新应用的oop遍历
	  gch->gen_process_roots(_level, //level就是0
	                         true,  //因为level是0,所以此参数实际无意义
	                         true,  // StrongRootsScope的active入参为true
	                         GenCollectedHeap::SO_ScavengeCodeCache, //只遍历nmethod中的oop
	                         GenCollectedHeap::StrongAndWeakRoots,//StrongAndWeakRoots是静态常量,值为false,表示会遍历weak root,如StringTable中的String对象
	                         &fsc_with_no_gc_barrier,
	                         &fsc_with_gc_barrier,
	                         &cld_scan_closure);
	 
	  //遍历所有promote到老年代的对象,恢复其对象头,遍历其引用类型属性
	  evacuate_followers.do_void();
	 
	  FastKeepAliveClosure keep_alive(this, &scan_weak_ref);
	  ReferenceProcessor* rp = ref_processor();
	  rp->setup_policy(clear_all_soft_refs);
	  //处理do_void方法遍历引用类型属性过程中找到的Reference实例,如果该实例的referent对象是存活的,则从待处理列表中移除,否则将referent属性置为null
	  const ReferenceProcessorStats& stats =
	  rp->process_discovered_references(&is_alive, &keep_alive, &evacuate_followers,
	                                    NULL, _gc_timer, gc_tracer.gc_id());
	  gc_tracer.report_gc_reference_stats(stats);
	 
	  if (!_promotion_failed) {
	    //promote没有失败的
	    //重置清空eden区和from区
	    eden()->clear(SpaceDecorator::Mangle);
	    from()->clear(SpaceDecorator::Mangle);
	    if (ZapUnusedHeapArea) {
	      to()->mangle_unused_area();
	    }
	    //交换from区和to区
	    swap_spaces();
	    //交换后,原来的from区变成to区,必须是空的
	    assert(to()->is_empty(), "to space should be empty now");
	    //调整tenuring_threshold
	    adjust_desired_tenuring_threshold();
	 
	    AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy();
	    //重置gc_overhead_limit_count
	    size_policy->reset_gc_overhead_limit_count();
	    if (PrintGC && !PrintGCDetails) {
	      gch->print_heap_change(gch_prev_used);
	    }
	    assert(!gch->incremental_collection_failed(), "Should be clear");
	  } else {
	    //如果存在promote失败的情形
	    assert(_promo_failure_scan_stack.is_empty(), "post condition");
	    //drain_promo_failure_scan_stack方法会负责处理掉里面保存的oop,遍历其所引用的其他oop,找到的oop的处理逻辑就是fsc_with_no_gc_barrier
	    //释放_promo_failure_scan_stack的内存,
	    _promo_failure_scan_stack.clear(true); // Clear cached segments.
	    //移除from区和eden区包含的对象的froward指针
	    remove_forwarding_pointers();
	    if (PrintGCDetails) {
	      gclog_or_tty->print(" (promotion failed) ");
	    }
	    //交换from区和to区,注意此时eden区和from区因为promote失败所以不是空的,还有存活对象
	    swap_spaces();   // For uniformity wrt ParNewGeneration.
	    //将to区作为from区的next_compaction_space,正常为NULL
	    from()->set_next_compaction_space(to());
	    //将incremental_collection_failed置为true
	    gch->set_incremental_collection_failed();
	 
	    //通知老年代promote失败,CMS老年代实际不做处理
	    _next_gen->promotion_failure_occurred();
	    gc_tracer.report_promotion_failed(_promotion_failed_info);
	  }
	  //设置并行遍历时的边界
	  from()->set_concurrent_iteration_safe_limit(from()->top());
	  to()->set_concurrent_iteration_safe_limit(to()->top());
	  SpecializationStats::print();
	 
	  //更新GC完成时间
	  jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
	  update_time_of_last_gc(now);
	 
	  gch->trace_heap_after_gc(&gc_tracer);
	  gc_tracer.report_tenuring_threshold(tenuring_threshold());
	 
	  _gc_timer->register_gc_end();
	  //更新GC日志
	  gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions());
	}

	oop DefNewGeneration::copy_to_survivor_space(oop old) {
	  assert(is_in_reserved(old) && !old->is_forwarded(),
	         "shouldn't be scavenging this oop");
	  size_t s = old->size();
	  oop obj = NULL;
	 
	  // Try allocating obj in to-space (unless too old)
	  if (old->age() < tenuring_threshold()) {
	    //如果对象的年龄低于tenuring_threshold,则该在to区申请一块同样大小的内存
	    obj = (oop) to()->allocate_aligned(s);
	  }
	 
	  // Otherwise try allocating obj tenured
	  if (obj == NULL) {
	    //如果如果对象的年龄大于tenuring_threshold或者to区申请内存失败
	    //则尝试将该对象复制到老年代
	    obj = _next_gen->promote(old, s);
	    if (obj == NULL) {
	      //复制失败
	      handle_promotion_failure(old);
	      return old;
	    }
	  } else {
	    //to区中申请内存成功
	    const intx interval = PrefetchCopyIntervalInBytes;
	    Prefetch::write(obj, interval);
	 
	    //对象复制
	    Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)obj, s);
	 
	    //增加年龄,并修改age_table,增加对应年龄的总对象大小
	    //注意此处是增加复制对象而非原来对象的分代年龄
	    obj->incr_age();
	    age_table()->add(obj, s);
	  }
	 
	  //将对象头指针指向新地址
	  old->forward_to(obj);
	 
	  return obj;
	}

 
}

//定义垃圾回收器使用的全局属性,并初始化分代内存及其他共享资源
// CollectorPolicy
//   G1CollectorPolicy 
//     G1CollectorPolicyExt
//   GenCollectorPolicy
//     TwoGenerationCollectorPolicy
//     	  ConcurrentMarkSweepPolicy 
//     	    ASConcurrentMarkSweepPolicy 
//     	  GenerationSizer 
//     	  MarkSweepPolicy 
//hotspot/src/share/vm/memory/collectorPolicy.hpp
class CollectorPolicy : public CHeapObj<mtGC> {
  //跟踪分代内存的性能的计数器
  GCPolicyCounters* _gc_policy_counters;
  //初始堆内存
  size_t _initial_heap_byte_size;
  //最大堆内存
  size_t _max_heap_byte_size;
  //最小堆内存
  size_t _min_heap_byte_size;
  //space分配粒度
  size_t _space_alignment;
  //heap分配粒度,_heap_alignment必须大于_space_alignment,且是_space_alignment的整数倍
  size_t _heap_alignment;
  //是否通过命令行参数设置了最大堆内存
  bool _max_heap_size_cmdline;
  //用来自适应调整堆内存大小的策略实现
  AdaptiveSizePolicy* _size_policy;
  //是否需要清除所有的软引用,当软引用清除结束,垃圾回收器会将其置为false
  bool _should_clear_all_soft_refs;
  //当GC刚清除完所有的软引用时会设置该属性为true,当返回mutator时被设置成false
  bool _all_soft_refs_clear;

  enum Name {
    CollectorPolicyKind,
    TwoGenerationCollectorPolicyKind,
    ConcurrentMarkSweepPolicyKind,
    ASConcurrentMarkSweepPolicyKind,
    G1CollectorPolicyKind
  };
  
  virtual CollectorPolicy::Name kind() {
    return CollectorPolicy::CollectorPolicyKind;
  }
}

//表示分代内存使用的CollectorPolicy
//hotspot/src/share/vm/memory/collectorPolicy.hpp
class GenCollectorPolicy : public CollectorPolicy {
  //gen0的内存最小值
  size_t _min_gen0_size;
  //gen0的内存初始值
  size_t _initial_gen0_size;
  //gen0的内存最大值
  size_t _max_gen0_size;
  //分代内存分配粒度,_gen_alignment必须被_space_alignment整除,_heap_alignment被_gen_alignment整除
  size_t _gen_alignment;
  //一种特殊的Generation实现
  GenerationSpec **_generations;

  HeapWord* GenCollectorPolicy::satisfy_failed_allocation(size_t size,
	                                                        bool   is_tlab) {
	  //获取Java堆                                                      
	  GenCollectedHeap *gch = GenCollectedHeap::heap();
	  //初始化GCCause
	  GCCauseSetter x(gch, GCCause::_allocation_failure);
	  HeapWord* result = NULL;
	 
	  assert(size != 0, "Precondition violated");
	  if (GC_locker::is_active_and_needs_gc()) {
	    // GC_locker是active说明还有线程处于JNI关键区未开始GC
	    if (!gch->is_maximal_no_gc()) {
	      result = expand_heap_and_allocate(size, is_tlab);
	    }
	    return result;   // could be null if we are out of space
	  } else if (!gch->incremental_collection_will_fail(false /* don't consult_young */)) {
	    //incremental_collection_will_fail表示如果执行增量收集是否会失败,参考上一次增量收集的结果
	    //如果可以执行增量收集
	    gch->do_collection(false            /* full */,
	                       false            /* clear_all_soft_refs */,
	                       size             /* size */,
	                       is_tlab          /* is_tlab */,
	                       number_of_generations() - 1 /* max_level */);
	  } else {
	    if (Verbose && PrintGCDetails) {
	      gclog_or_tty->print(" :: Trying full because partial may fail :: ");
	    }
	    //执行全量的full GC
	    gch->do_collection(true             /* full */,
	                       false            /* clear_all_soft_refs */,
	                       size             /* size */,
	                       is_tlab          /* is_tlab */,
	                       number_of_generations() - 1 /* max_level */);
	  }
	  //尝试分配内存
	  result = gch->attempt_allocation(size, is_tlab, false /*first_only*/);
	 
	  if (result != NULL) {
	    //分配成功
	    assert(gch->is_in_reserved(result), "result not in heap");
	    return result;
	  }
	 
	  //分配失败,尝试扩展Java堆并分配内存
	  result = expand_heap_and_allocate(size, is_tlab);
	  if (result != NULL) {
	    return result;
	  }
	 
	  //分配失败,说明已经内存不足了,这时需要强制清理软引用,强制压实Java堆,任何可能的获取可用内存的方法都会执行,尽管代价昂贵
	  //如果尝试失败,抛出OOM异常
	  {
	    UIntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
	 
	    gch->do_collection(true             /* full */,
	                       true             /* clear_all_soft_refs */,
	                       size             /* size */,
	                       is_tlab          /* is_tlab */,
	                       number_of_generations() - 1 /* max_level */);
	  }
	 
	  //再次尝试分配内存
	  result = gch->attempt_allocation(size, is_tlab, false /* first_only */);
	  if (result != NULL) {
	    assert(gch->is_in_reserved(result), "result not in heap");
	    return result;
	  }
	  //分配失败,软引用已经清理的,标志位被置为false
	  assert(!should_clear_all_soft_refs(),
	    "Flag should have been handled and cleared prior to this point");
	 
	  return NULL;
	}
 

}

//表示一个只有两个Generation的CollectorPolicy,现有的GenCollectedHeap的所有子类都是只有两个Generation,第一个Generation相同,对应GenCollectorPolicy中新增的gen0的相关属性,第二个Generation的实现各不相同。TwoGenerationCollectorPolicy增加了第二个Generation即gen1相关的属性
//hotspot/src/share/vm/memory/collectorPolicy.hpp
class TwoGenerationCollectorPolicy : public GenCollectorPolicy {
  //gen1的内存最小值
  size_t _min_gen1_size;
  //gen1的内存初始值
  size_t _initial_gen1_size;
  //gen1的内存最大值
  size_t _max_gen1_size;
}

//UseAdaptiveSizePolicy为false时使用的CollectorPolicy实现.该类没有添加新的属性
//hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp
class ConcurrentMarkSweepPolicy : public TwoGenerationCollectorPolicy {
	void ConcurrentMarkSweepPolicy::initialize_alignments() {
	  //初始化_space_alignment等属性
	  _space_alignment = _gen_alignment = (uintx)Generation::GenGrain;
	  _heap_alignment = compute_heap_alignment();
	}
	 
	void ConcurrentMarkSweepPolicy::initialize_generations() {
	  //初始化_generations
	  _generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC,
	    CURRENT_PC, AllocFailStrategy::RETURN_NULL);
	  if (_generations == NULL)
	    vm_exit_during_initialization("Unable to allocate gen spec");
	  //UseParNewGC表示在新生代使用并发收集,默认为false
	  if (UseParNewGC) {
	    if (UseAdaptiveSizePolicy) {
	      _generations[0] = new GenerationSpec(Generation::ASParNew,
	                                           _initial_gen0_size, _max_gen0_size);
	    } else {
	      _generations[0] = new GenerationSpec(Generation::ParNew,
	                                           _initial_gen0_size, _max_gen0_size);
	    }
	  } else {
	    _generations[0] = new GenerationSpec(Generation::DefNew,
	                                         _initial_gen0_size, _max_gen0_size);
	  }
	  //UseAdaptiveSizePolicy表示使用自适应策略动态调整各代的大小,默认为true
	  if (UseAdaptiveSizePolicy) {
	    _generations[1] = new GenerationSpec(Generation::ASConcurrentMarkSweep,
	                            _initial_gen1_size, _max_gen1_size);
	  } else {
	    _generations[1] = new GenerationSpec(Generation::ConcurrentMarkSweep,
	                            _initial_gen1_size, _max_gen1_size);
	  }
	 
	  if (_generations[0] == NULL || _generations[1] == NULL) {
	    //如果初始化失败,则退出
	    vm_exit_during_initialization("Unable to allocate gen spec");
	  }
	}
	 
	int number_of_generations()          { return 2; }
}

//UseAdaptiveSizePolicy为true时使用的CollectorPolicy实现.该类没有添加新的属性
//hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp
class ASConcurrentMarkSweepPolicy : public ConcurrentMarkSweepPolicy {
}

垃圾收集器的初始化

根据《JVM内存池》一文中,堆内存初始化

jint Universe::initialize_heap() {

  if (UseParallelGC) {
    Universe::_collectedHeap = new ParallelScavengeHeap();
  } else if (UseG1GC) {
    G1CollectorPolicyExt* g1p = new G1CollectorPolicyExt();
    g1p->initialize_all();
    G1CollectedHeap* g1h = new G1CollectedHeap(g1p);
    Universe::_collectedHeap = g1h;
  } else {
    //主要存储各种不同收集器堆的模型参数
    GenCollectorPolicy *gc_policy;

    if (UseSerialGC) {
      gc_policy = new MarkSweepPolicy();
    } else if (UseConcMarkSweepGC) {
      if (UseAdaptiveSizePolicy) {
        gc_policy = new ASConcurrentMarkSweepPolicy();
      } else {
        //cms堆的模型参数
        gc_policy = new ConcurrentMarkSweepPolicy();
      }
    } else { // default old generation
      gc_policy = new MarkSweepPolicy();
    }
    //根据JVM参数,对堆模型参数初始化
    gc_policy->initialize_all();

    Universe::_collectedHeap = new GenCollectedHeap(gc_policy);
  }
  //eden中tlab表申请
  ThreadLocalAllocBuffer::set_max_size(Universe::heap()->max_tlab_size());
  //堆申请,及分带初始化
  jint status = Universe::heap()->initialize();
  if (status != JNI_OK) {
    return status;
  }
  // .....
}  

其中最常用的为cms垃圾收集器。其触发参数为

-XX:+UseConcMarkSweepGC
-XX:+UseParNewGC

  1. Policy中根据参数设置分代数据,根据参数并行gc线程

Threads::create_vm()《openJdk的启动流程》中的方法
  init_globals()
  Universe::universe_init()
   Universe::initialize_heap()
    ConcurrentMarkSweepPolicy::initialize_all
     ConcurrentMarkSweepPolicy::initialize_generations # 分代数据设置
    GenCollectedHeap::GenCollectedHeap
     SharedHeap::SharedHeap # GC线程创建

//年轻代参数设置
 _generations[0] = new GenerationSpec(Generation::ParNew,
                                           _initial_gen0_size, _max_gen0_size);
 
//老年代参数设置                                           
_generations[1] = new GenerationSpec(Generation::ConcurrentMarkSweep,
                            _initial_gen1_size, _max_gen1_size);
//初始化执行并行GC的线程池 
_workers = new FlexibleWorkGang("Parallel GC Threads", ParallelGCThreads,
                            /* are_GC_task_threads */true,
                            /* are_ConcurrentGC_threads */false);
  1. 根据分代参数,具体初始化分代

Threads::create_vm()《openJdk的启动流程》中的方法
  init_globals()
  Universe::universe_init()
   Universe::initialize_heap()
    GenCollectedHeap::initialize()

  //根据各GenerationSpec的最大大小计算总的需要保留的内存空间,然后申请指定大小的连续内存空间
heap_address = allocate(heap_alignment, &total_reserved,
                          &n_covered_regions, &heap_rs);

//分带初始化 
_gen_specs[i]->init(this_rs, i, rem_set()); 

//年轻代
new ParNewGeneration(rs, init_size(), 0);
//老年代
new ConcurrentMarkSweepGeneration(rs,
               init_size(), 1, ctrs, UseCMSAdaptiveFreeLists,
                 (FreeBlockDictionary<FreeChunk>::DictionaryChoice)CMSDictionaryChoice);                         
  1. 验证堆模型的正确性,及进一些初始化参数,具体参考GenCollectedHeap::post_initialize

垃圾收集触发

  1. 创建vm_threads,用于处理虚拟机各种延时任务

Threads::create_vm()《openJdk的启动流程》中的方法
  VMThread::create()

  1. 编写一触放eden垃圾回收代码
/*-verbose:gc
-Xms20M
-Xmx20M
-Xmn10M
-XX:SurvivorRatio=8
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+UseConcMarkSweepGC
-XX:MaxTenuringThreshold=1*/       
       byte[] b1, b2, b3, b4;
       b1 = new byte[2 * _1MB];
       b2 = new byte[2* _1MB];
       b3 = new byte[2* _1MB];
       b2 = null;
       b3 = null;
       b4 = new byte[2* _1MB]; //eden用完,必须回收
  1. 内存申请失败生成VM_GenCollectForAllocation并向vm_threads提交

创建b4时通过JNI调用
InterpreterRuntime::newarray
  TypeArrayKlass::allocate_common
    CollectedHeap::common_mem_allocate_init
     GenCollectorPolicy::mem_allocate_work

//VM_GenCollectForAllocation是内存分配失败触发垃圾回收,然后尝试分配内存的操作
VM_GenCollectForAllocation op(size, is_tlab, gc_count_before);
VMThread::execute(&op);
  1. VMThread处理VM_GenCollectForAllocation事件,进行垃圾回收

VMThread::run
  VMThread::loop
    VM_Operation::evaluate
     VM_GenCollectForAllocation::doit
       GenCollectorPolicy::satisfy_failed_allocation

//如果执行增量收集是否会失败,参考上一次增量收集的结果
if(!incremental_collection_will_fail(false)){
    //如果可以执行增量收集
    gch->do_collection(false            /* full */,
                       false            /* clear_all_soft_refs */,
                       size             /* size */,
                       is_tlab          /* is_tlab */,
                       number_of_generations() - 1 /* max_level */);
}else{
    //执行全量的full GC
    gch->do_collection(true             /* full */,
                       false            /* clear_all_soft_refs */,
                       size             /* size */,
                       is_tlab          /* is_tlab */,
                       number_of_generations() - 1 /* max_level */);
}
  1. 根据上例子do_collection执行流程为
int starting_level = 0;
boolean full = false;
int max_level = 1;
//full为false,空间不充足
ParNewGeneration.should_collect() //返回true
ParNewGeneration.collect(full, do_clear_all_soft_refs, size, is_tlab);
//full为false,空间充足
ConcurrentMarkSweepGeneration.should_collect() //false

ParNew年轻代

  1. 年轻代初始化

Threads::create_vm()《openJdk的启动流程》中的方法
  init_globals()
  Universe::universe_init()
   Universe::initialize_heap()
    GenCollectedHeap::initialize
     GenerationSpec::init
      ParNewGeneration::ParNewGeneration
       DefNewGeneration::DefNewGeneration

//总体申请了个_virtual_space空间
//其中又用EdenSpace,ContiguousSpace进行进一步划分
_eden_space = new EdenSpace(this);
_from_space = new ContiguousSpace();
_to_space   = new ContiguousSpace();
//计算survivor区和eden区的最大空间,即年轻代最大内存时survivor区和eden区的内存空间
  uintx size = _virtual_space.reserved_size();
  _max_survivor_size = compute_survivor_size(size, alignment);
  _max_eden_size = size - (2*_max_survivor_size);
//计算三个内存区的大小和边界,并初始化
  compute_space_boundaries(0, SpaceDecorator::Clear, SpaceDecorator::Mangle);
  1. 年轻代对象分配主要在eden区,只有在eden区和老年代都满了,才可能在from区中分配内存,正常情况下to区是空的

数组创建时通过JNI调用
InterpreterRuntime::newarray
  TypeArrayKlass::allocate_common
    CollectedHeap::common_mem_allocate_init
     GenCollectorPolicy::mem_allocate_work
      GenCollectedHeap::attempt_allocation
       DefNewGeneration::allocate

//正常请求分配eden的空间
//word_size为此次对象所要的空间
HeapWord* result = eden()->par_allocate(word_size);
if (result != NULL) {
    return result;
}
//从from申请空间
result = allocate_from_space(word_size);
  1. 年轻代垃圾收集ParNewGeneration.collect
  //FastScanClosure用来遍历年轻代中的存活对象oop,第二个参数为true,表示会将oop对应的卡表项置为youngergen_card
  FastScanClosure fsc_with_no_gc_barrier(this, false);
  FastScanClosure fsc_with_gc_barrier(this, true);
  KlassScanClosure klass_scan_closure(&fsc_with_no_gc_barrier,
                                      gch->rem_set()->klass_rem_set());
  //CLDToKlassAndOopClosure用来遍历一个ClassLoader加载的所有类对应的Class实例和依赖等                                    
  CLDToKlassAndOopClosure cld_scan_closure(&klass_scan_closure,
                                           &fsc_with_no_gc_barrier,
                                           false)

      //上面把所有的遍历器都准备好了,遍历器的底层原理是space 
      //gen_process_roots用于遍历处理ClassLoaderDataGraph,Threads,Universe等组件中包含的oop,将这些oop作为根节点遍历其所引用的其他oop,根据参数还能遍历年轻代和老年代中的所有oop,遍历脏的卡表项对应的内存区域中包含的oop
	  gch->gen_process_roots(_level, //level就是0
	                         true,  //因为level是0,所以此参数实际无意义
	                         true,  // StrongRootsScope的active入参为true
	                         GenCollectedHeap::SO_ScavengeCodeCache, //只遍历nmethod中的oop
	                         GenCollectedHeap::StrongAndWeakRoots,//StrongAndWeakRoots是静态常量,值为false,表示会遍历weak root,如StringTable中的String对象
	                         &fsc_with_no_gc_barrier,
	                         &fsc_with_gc_barrier,
	                         &cld_scan_closure);
	 
  1. promote 操作

DefNewGeneration::collect
  GenCollectedHeap::gen_process_roots
    ClassLoaderDataGraph::roots_cld_do
     FastScanClosure::do_oop
      DefNewGeneration::copy_to_survivor_space

if (old->age() < tenuring_threshold()) {
    //如果对象的年龄低于tenuring_threshold,则该在to区申请一块同样大小的内存
    obj = (oop) to()->allocate_aligned(s);
}
if(obj == null){
    //如果如果对象的年龄大于tenuring_threshold或者to区申请内存失败
    //则尝试将该对象复制到老年代
    obj = _next_gen->promote(old, s);
    if (obj == NULL) {
      //复制失败
      handle_promotion_failure(old);
      return old;
    }
}else{
   //to区中申请内存成功
}

//将对象头指针指向新地址
old->forward_to(obj);
//promote就是指将某个存活对象oop从eden区拷贝到from区或者老年代的过程
//如果对象年龄大于阈值则拷贝到老年代,否则拷贝到to区
//如果to区内存不足则拷贝到老年代
//如果老年代空间不足则会临时保存该oop,因为有可能是该对象较大,此时其他较小的对象可以正常promote成功的。
//从to区或者老年代按照对象大小分配好同样大小的内存后,就会将旧对象的数据复制到新分配的内存上,然后增加复制对象的对象年龄,最后将复制对象的地址写入原对象的对象头中并打标,这个动作就是forword。

CMS老年代垃圾收集

待续

主要参数

《hotspot实战》
Hotspot 垃圾回收之VM_Operation 源码解析
Hotspot 垃圾回收之CollectedHeap 源码解析
Hotspot 垃圾回收之GenCollectedHeap 源码解析
Hotspot 垃圾回收之CompactibleSpace 源码解析
Hotspot 垃圾回收之EdenSpace 源码解析
Hotspot 垃圾回收之DefNewGeneration(一) 源码解析
Hotspot 垃圾回收之DefNewGeneration(二) 源码解析
Hotspot 垃圾回收之CollectorPolicy (一) 源码解析
Hotspot 垃圾回收之CollectorPolicy (二) 源码解析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值