以    UseSerialGC为例







JVM在创建堆结构时,会沿用如此堆栈顺序



    Universe::initialize_heap()                    Universe对象初始化堆结构



                代码:   GenCollectorPolicy gc_policy = new MarkSweepPolicy();     创建垃圾回收策略为标记清除垃圾回收对象



                代码:   Universe::_collectedHeap = new GenCollectedHeap(gc_policy);        创建堆为代回收堆



                代码:   Universe::heap()->initialize();                    堆初始化



    1、创建垃圾回收策略为标记清除垃圾回收对象new MarkSweepPolicy()



                initialize_all()



                    调用:    initialize_flags();                初始化一些标记,例如NewSize,MaxNewSize,PermSize,MaxPermSize,MinPermHeapExpansion,MaxPermHeapExpansion,MinHeapDeltaBytes,SharedReadOnlySize,SharedReadWriteSize,SharedMiscDataSize等



                    调用:    initialize_size_info();          初始化一些大小,例如min_gen0_size,initial_gen0_size,max_gen0_size等



                    调用:    initialize_generations();      初始化代信息



                                调用:    initialize_perm_generation(PermGen::MarkSweepCompact);                   初始化永久代信息



                                            代码:    _permanent_generation = new PermanentGenerationSpec(pgnm, PermSize, MaxPermSize, SharedReadOnlySize, SharedReadWriteSize, SharedMiscDataSize, SharedMiscCodeSize);            初始化永久代信息



                                代码:    _generations = new GenerationSpecPtr[number_of_generations()];            初始化特殊的代信息指针

                                代码:    _generations[0] = new GenerationSpec(Generation::ParNew, _initial_gen0_size, _max_gen0_size);        并行回收的年轻代特殊对象          



                                           _generations[0] = new GenerationSpec(Generation::DefNew, _initial_gen0_size, _max_gen0_size);        普通的年轻代特殊对象



                                代码:    _generations[1] = new GenerationSpec(Generation::MarkSweepCompact, _initial_gen1_size, _max_gen1_size);    标记清楚的代对象特殊对象



    2、创建代回收堆,并设置垃圾回收策略为标记清除垃圾回收对象Universe::_collectedHeap = new GenCollectedHeap(gc_policy);



                调用构造方法:    GenCollectedHeap(GenCollectorPolicy policy)



                           调用父类构造方法:    SharedHeap(CollectorPolicy policy)



                                                        调用父类构造方法:    CollectedHeap()             一些参数的设置



                                                                    代码:    const size_t max_len = size_t(arrayOopDesc::max_array_length(T_INT));



                                                                               const size_t elements_per_word = HeapWordSize / sizeof(jint);



                                                        代码:    if ((UseParNewGC ||(UseConcMarkSweepGC && CMSParallelRemarkEnabled) ||UseG1GC) &&ParallelGCThreads > 0) {



                                                                                FlexibleWorkGang _workers = new FlexibleWorkGang(“Parallel GC Threads”, ParallelGCThreads,true,false);



                                                                   }




                                                                   _workers->initialize_workers();



                代码:    _gen_policy(policy),_gen_process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)),



    3、对堆进行格式化Universe::heap()->initialize();



                调用:    GenCollectedHeap-::initialize();



                                调用:    CollectedHeap::pre_initialize();



                                            代码:    _defer_initial_card_mark = ReduceInitialCardMarks && can_elide_tlab_store_barriers() && (DeferInitialCardMark || card_mark_must_follow_store());



                                代码:    char heap_address = allocate(alignment, perm_gen_spec, &total_reserved, &n_covered_regions, &heap_rs);           分配代内存,映射到指定位置



                                            代码:     total_reserved = _gen_specs[0]->max_size() + _gen_specs[1]->max_size() + perm_gen_spec->max_size() + perm_gen_spec->misc_data_size() + perm_gen_spec->misc_code_size();    计算总可占用的最大内存大小



                                            代码:     _n_covered_regions = _gen_specs[0]->n_covered_regions() + _gen_specs[1]->n_covered_regions() + perm_gen_spec->n_covered_regions()                         计算总可占用的最大内存分片数量




                                            代码:    char heap_address  = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop);         设置一些这样或者那样的属性




                                            代码:    ReservedSpace heap_rs = ReservedHeapSpace(total_reserved, alignment,UseLargePages, heap_address);     申请内存并创建到指定映射




                                                       调用父类构造函数:    ReservedSpace::ReservedSpace(size_t size, size_t alignment, bool large, char requested_address, const size_t noaccess_prefix)



                                                                                    调用函数:    void ReservedSpace::initialize(size_t size, size_t alignment, bool large, char requested_address,const size_t noaccess_prefix, bool executable)



                                                                                                        代码:    char base =os::reserve_memory(size, NULL, alignment);    申请内存并映射



                                                                                                                   调用:    os::reserve_memory()



                                                                                                                              代码:    return anon_mmap(requested_addr, bytes, (requested_addr != NULL));



                                                                                                                                         代码:    char addr = (char)::mmap(requested_addr, bytes, PROT_READ|PROT_WRITE,flags, -1, 0);        调用原生Linux函数mmap,申请到一个可读可写的内存映射,大小为bytes  



                                                                                                        代码:    char  _base = addr;




                                                                                                        代码:    size_t _size = size;



                                                                                                        代码:    size_t _noaccess_prefix = prefix_align;



                                                                                                        代码:    size_t _alignment = noaccess_prefix;



                                                        调用:    protect_noaccess_prefix(size)




                                                                   调用父类函数:    ReservedSpace::protect_noaccess_prefix(const size_t size)                                对内存的起始位置进行调整




                                代码:    _reserved = MemRegion((HeapWord)heap_rs.base(),(HeapWord)(heap_rs.base() + heap_rs.size()));                    创造MemRegion内存分片对象




                                           代码:    HeapWord _start = start;



                                           代码:    size_t    _word_size;




                                代码:    _rem_set = collector_policy()->create_rem_set(_reserved, n_covered_regions);                                                    创造原子性内存块集合



                                           调用:    CollectorPolicy::create_rem_set(MemRegion whole_heap,int max_covered_regions)



                                                        代码:    CardTableRS res = new CardTableRS(whole_heap, max_covered_regions);                                创造card table 




                                                                    调用父类构造函数:    GenRemSet()                                                                                       // A GenRemSet provides ways of iterating over pointers accross generations.



                                                                                                                                                                                                          内部全是虚函数,都在CardTableRS中实现



                                                                    代码:    _ct_bs = new CardTableModRefBSForCTRS(whole_heap, max_covered_regions);



                                                                                调用父类构造函数:    ModRefBarrierSet(max_covered_regions)



                                                                                代码:    _kind = BarrierSet::CardTableModRef



                                                                                代码:    HeapWord low_bound  = _whole_heap.start();



                                                                                代码:    HeapWord high_bound = _whole_heap.end();



                                                                                代码:    MemRegion _covered = new MemRegion[max_covered_regions];                    // The covered regions should be in address order.这个分片必须按内存地址进行排序



                                                                                代码:    MemRegion _committed = new MemRegion[max_covered_regions];                // The committed regions correspond one-to-one to the covered regions.这个是否已提交分片必须与covered regions一一对应



                                                                                代码:    MemRegion _guard_region = MemRegion((HeapWord)guard_page, _page_size);//The last card is a guard card, and we commit the page for it so




                                                                                                                                                                                                         //we can use the card for verification purposes. We make sure we never



                                                                                                                                                                                                         //uncommit the MemRegion for that page.



                                                                                                                                                                                                        最后一个card是一个警戒card,我们能用这块内存来实现某种指定的意图,我们需要保证我们从不操作这块内存



                                                                                代码:    typedef jbyte  CardPtr;



                                                                                           typedef CardPtr CardArr;



                                                                                           CardArr _lowest_non_clean = NEW_C_HEAP_ARRAY(CardArr, max_covered_regions);



                                                                                           size_t  _lowest_non_clean_chunk_size = NEW_C_HEAP_ARRAY(size_t, max_covered_regions)



                                                                                           uintptr_t _lowest_non_clean_base_chunk_index = NEW_C_HEAP_ARRAY(uintptr_t, max_covered_regions)



                                                                                           int _last_LNC_resizing_collection = NEW_C_HEAP_ARRAY(int, max_covered_regions)



                                                                                                // This is an array, one element per covered region of the card table.



                                                                                                // Each entry is itself an array, with one element per chunk in the



                                                                                                // covered region.  Each entry of these arrays is the lowest non-clean



                                                                                                // card of the corresponding chunk containing part of an object from the



                                                                                                // previous chunk, or else NULL.



                                                                                                英语很好懂,不解释。大意是每个array的元素是另一个array,每个二级array储存的是在当前region分片中的元素的chunk数组




                                                                                                因此,可知JVM内存分配中采用BarrierSet来对内存的每一个chunk进行管理



                                                                    代码:    set_bs(_ctbs);



                                代码:    set_barrier_set(rem_set()->bs());




                                代码:    _perm_gen = perm_gen_spec->init(heap_rs, PermSize, rem_set());



                                            调用:    PermanentGenerationSpec::init(ReservedSpace rs,size_t init_size,GenRemSet *remset)



                                                        代码:    ReservedSpace perm_rs = rs.first_part(_max_size, UseSharedSpaces,UseSharedSpaces);        获取到第一块可用的内存?



                                                                    代码:    ReservedSpace result(base(), partition_size, alignment, special(),executable());



                                                                                代码;    addr = os::attempt_reserve_memory_at(size, requested_address);        申请一块内存并放入ReservedSpace(此处与上处代码相同,走的是requested_address不为空的分支)



                                                        代码:    ReservedSpace shared_rs = rs.last_part(_max_size);        申请获取最后一块内存(此处需要研究,在申请第一块和最后一块之后,是否中间的内存就全部申请完成)




                                代码:    clear_incremental_collection_failed








                                至此内存代分配结束;