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 (二) 源码解析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JVM垃圾回收是Java虚拟机的一个重要功能,它的知识体系包括以下内容: 1. 垃圾回收算法:垃圾回收算法是指垃圾回收器采用的垃圾回收策略。常见的垃圾回收算法包括标记-清除、复制、标记-压缩和分代等。 2. 垃圾回收器:垃圾回收器是JVM的一个组成部分,它负责执行垃圾回收算法,并回收Java对象的内存空间。常见的垃圾回收器包括Serial、Parallel、CMS、G1等。 3. 对象存活判定:垃圾回收器需要判断哪些Java对象是可以回收的,哪些是必须保留的。存活对象可以通过引用计数、可达性分析等方式判断。 4. 垃圾回收的过程:垃圾回收的过程包括标记、清除、整理等阶段。标记阶段是找到存活对象的过程,清除阶段是回收无用对象的过程,整理阶段是将存活对象移动到一块连续的内存区域中。 5. 垃圾回收的性能优化:垃圾回收的性能优化包括分代、增量、并发、预处理等技术。分代是指将Java对象分为年轻代和老年代,以便针对不同的对象有针对性地进行垃圾回收。 6. 垃圾回收的调优和监控:垃圾回收的调优和监控可以通过调整堆大小、设置垃圾回收器类型、调整垃圾回收的参数等方式实现。 JVM垃圾回收是Java虚拟机的一个重要功能,掌握其知识体系可以帮助程序员更好地理解Java程序的内存模型和垃圾回收机制,从而编写出高效、可靠的Java程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值