jint ParallelScavengeHeap::initialize() { // Cannot be initialized until after the flags are parsed GenerationSizer flag_parser; size_t max_young_size = flag_parser.max_young_gen_size(); size_t max_old_size = flag_parser.max_old_gen_size(); if (UseMPSS && max_young_size + max_old_size >= LargePageHeapSizeThreshold) { set_generation_alignment(LargePageSizeInBytes); } const size_t alignment = generation_alignment(); // Check alignments // NEEDS_CLEANUP The default TwoGenerationCollectorPolicy uses // NewRatio; it should check UseAdaptiveSizePolicy. Changes from // generationSizer could move to the common code. size_t min_young_size = align_size_up(flag_parser.min_young_gen_size(), alignment); size_t young_size = align_size_up(flag_parser.young_gen_size(), alignment); max_young_size = align_size_up(max_young_size, alignment); size_t min_old_size = align_size_up(flag_parser.min_old_gen_size(), alignment); size_t old_size = align_size_up(flag_parser.old_gen_size(), alignment); old_size = MAX2(old_size, min_old_size); max_old_size = align_size_up(max_old_size, alignment); size_t perm_size = align_size_up(flag_parser.perm_gen_size(), alignment); size_t max_perm_size = align_size_up(flag_parser.max_perm_gen_size(), alignment); // Calculate the total size. size_t total_reserved = max_young_size + max_old_size + max_perm_size; if (UseISM || UsePermISM) { total_reserved = round_to(total_reserved, LargePageSizeInBytes); } ReservedSpace heap_rs(total_reserved, alignment, UseISM || UsePermISM); if (!heap_rs.is_reserved()) { vm_shutdown_during_initialization( "Could not reserve enough space for object heap"); return JNI_ENOMEM; } _reserved_byte_size = heap_rs.size(); _reserved = MemRegion((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size())); HeapWord* boundary = (HeapWord*)(heap_rs.base() + max_young_size); CardTableExtension* card_table_barrier_set = new CardTableExtension(_reserved, 3); _barrier_set = card_table_barrier_set; oopDesc::set_bs(_barrier_set); if (_barrier_set == NULL) { vm_shutdown_during_initialization( "Could not reserve enough space for barrier set"); return JNI_ENOMEM; } // Initial young gen size is 4 Mb size_t init_young_size = align_size_up(4 * M, alignment); init_young_size = MAX2(MIN2(init_young_size, max_young_size), young_size); // Divide up the reserved space: perm, old, young ReservedSpace perm_rs = heap_rs.first_part(max_perm_size); ReservedSpace old_young_rs = heap_rs.last_part(max_perm_size); ReservedSpace old_rs = old_young_rs.first_part(max_old_size); heap_rs = old_young_rs.last_part(max_old_size); ReservedSpace young_rs = heap_rs.first_part(max_young_size); assert(young_rs.size() == heap_rs.size(), "Didn't reserve all of the heap"); // Make up the generations // Calculate the maximum size that a generation can grow. This // includes growth into the other generation. Note that the // parameter _max_gen_size is kept as the maximum // size of the generation as the boundaries currently stand. // _max_gen_size is still used as that value. double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0; double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0; // Regarding SEPARATE_PATHS. If SEPARATE_PATHS is defined, then // the generations are created without the use of AdjoiningGenerations // in the case where boundary moving is not an option. This is // being kept until the code review in case there is some desire // to keep the new code out of the path of the previous code. // One effect of using AdjoiningGenerations for both cases is that // is that the generations in AdjoiningGenerations need to be // PSOldGen and PSYoungGen as opposed to ASPSOldGen and ASPSYoungGen. // This latter means that methods such as available_for_expansion() // need to be defined in PSOldGen. #undef SEPARATE_PATHS #ifdef SEPARATE_PATHS if (UseAdaptiveSizePolicy && UseAdaptiveGCBoundary) { #endif _gens = new AdjoiningGenerations(old_young_rs, old_size, min_old_size, max_old_size, init_young_size, min_young_size, max_young_size, alignment); _old_gen = _gens->old_gen(); _young_gen = _gens->young_gen(); _size_policy = new PSAdaptiveSizePolicy(young_gen()->eden_space()->capacity_in_bytes(), old_gen()->capacity_in_bytes(), young_gen()->to_space()->capacity_in_bytes(), generation_alignment(), intra_generation_alignment(), max_gc_pause_sec, max_gc_minor_pause_sec, GCTimeRatio ); #ifdef SEPARATE_PATHS } else { // Same as for case where boundary does not move. size_t old_size_limit, young_size_limit; old_size_limit = max_old_size; young_size_limit = max_young_size; _young_gen = new PSYoungGen(init_young_size, min_young_size, max_young_size); _old_gen = new PSOldGen(old_size, min_old_size, max_old_size, "old", 1); _gens = 0; _young_gen->initialize(young_rs, alignment); _old_gen->initialize(old_rs, alignment, "old", 1); _size_policy = new PSAdaptiveSizePolicy(young_gen()->eden_space()->capacity_in_bytes(), old_gen()->capacity_in_bytes(), young_gen()->to_space()->capacity_in_bytes(), generation_alignment(), intra_generation_alignment(), max_gc_pause_sec, max_gc_minor_pause_sec, GCTimeRatio ); } #endif _perm_gen = new PSPermGen(perm_rs, alignment, perm_size, perm_size, max_perm_size, "perm", 2); assert(!UseAdaptiveGCBoundary || (old_gen()->virtual_space()->high_boundary() == young_gen()->virtual_space()->low_boundary()), "Boundaries must meet"); // initialize the policy counters - 2 collectors, 3 generations _gc_policy_counters = new PSGCAdaptivePolicyCounters("ParScav:MSC", 2, 3, _size_policy); _psh = this; return JNI_OK; }
jint ParallelScavengeHeap::initialize() { CollectedHeap::pre_initialize(); // Cannot be initialized until after the flags are parsed // GenerationSizer flag_parser; _collector_policy = new GenerationSizer(); size_t yg_min_size = _collector_policy->min_young_gen_size(); size_t yg_max_size = _collector_policy->max_young_gen_size(); size_t og_min_size = _collector_policy->min_old_gen_size(); size_t og_max_size = _collector_policy->max_old_gen_size(); // Why isn't there a min_perm_gen_size()? size_t pg_min_size = _collector_policy->perm_gen_size(); size_t pg_max_size = _collector_policy->max_perm_gen_size(); trace_gen_sizes("ps heap raw", pg_min_size, pg_max_size, og_min_size, og_max_size, yg_min_size, yg_max_size); // The ReservedSpace ctor used below requires that the page size for the perm // gen is <= the page size for the rest of the heap (young + old gens). const size_t og_page_sz = os::page_size_for_region(yg_min_size + og_min_size, yg_max_size + og_max_size, 8); const size_t pg_page_sz = MIN2(os::page_size_for_region(pg_min_size, pg_max_size, 16), og_page_sz); const size_t pg_align = set_alignment(_perm_gen_alignment, pg_page_sz); const size_t og_align = set_alignment(_old_gen_alignment, og_page_sz); const size_t yg_align = set_alignment(_young_gen_alignment, og_page_sz); // Update sizes to reflect the selected page size(s). // // NEEDS_CLEANUP. The default TwoGenerationCollectorPolicy uses NewRatio; it // should check UseAdaptiveSizePolicy. Changes from generationSizer could // move to the common code. yg_min_size = align_size_up(yg_min_size, yg_align); yg_max_size = align_size_up(yg_max_size, yg_align); size_t yg_cur_size = align_size_up(_collector_policy->young_gen_size(), yg_align); yg_cur_size = MAX2(yg_cur_size, yg_min_size); og_min_size = align_size_up(og_min_size, og_align); og_max_size = align_size_up(og_max_size, og_align); size_t og_cur_size = align_size_up(_collector_policy->old_gen_size(), og_align); og_cur_size = MAX2(og_cur_size, og_min_size); pg_min_size = align_size_up(pg_min_size, pg_align); pg_max_size = align_size_up(pg_max_size, pg_align); size_t pg_cur_size = pg_min_size; trace_gen_sizes("ps heap rnd", pg_min_size, pg_max_size, og_min_size, og_max_size, yg_min_size, yg_max_size); const size_t total_reserved = pg_max_size + og_max_size + yg_max_size; char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop); // The main part of the heap (old gen + young gen) can often use a larger page // size than is needed or wanted for the perm gen. Use the "compound // alignment" ReservedSpace ctor to avoid having to use the same page size for // all gens. ReservedHeapSpace heap_rs(pg_max_size, pg_align, og_max_size + yg_max_size, og_align, addr); if (UseCompressedOops) { if (addr != NULL && !heap_rs.is_reserved()) { // Failed to reserve at specified address - the requested memory // region is taken already, for example, by 'java' launcher. // Try again to reserver heap higher. addr = Universe::preferred_heap_base(total_reserved, Universe::ZeroBasedNarrowOop); ReservedHeapSpace heap_rs0(pg_max_size, pg_align, og_max_size + yg_max_size, og_align, addr); if (addr != NULL && !heap_rs0.is_reserved()) { // Failed to reserve at specified address again - give up. addr = Universe::preferred_heap_base(total_reserved, Universe::HeapBasedNarrowOop); assert(addr == NULL, ""); ReservedHeapSpace heap_rs1(pg_max_size, pg_align, og_max_size + yg_max_size, og_align, addr); heap_rs = heap_rs1; } else { heap_rs = heap_rs0; } } } os::trace_page_sizes("ps perm", pg_min_size, pg_max_size, pg_page_sz, heap_rs.base(), pg_max_size); os::trace_page_sizes("ps main", og_min_size + yg_min_size, og_max_size + yg_max_size, og_page_sz, heap_rs.base() + pg_max_size, heap_rs.size() - pg_max_size); if (!heap_rs.is_reserved()) { vm_shutdown_during_initialization( "Could not reserve enough space for object heap"); return JNI_ENOMEM; } _reserved = MemRegion((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size())); CardTableExtension* const barrier_set = new CardTableExtension(_reserved, 3); _barrier_set = barrier_set; oopDesc::set_bs(_barrier_set); if (_barrier_set == NULL) { vm_shutdown_during_initialization( "Could not reserve enough space for barrier set"); return JNI_ENOMEM; } // Initial young gen size is 4 Mb // // XXX - what about flag_parser.young_gen_size()? const size_t init_young_size = align_size_up(4 * M, yg_align); yg_cur_size = MAX2(MIN2(init_young_size, yg_max_size), yg_cur_size); // Split the reserved space into perm gen and the main heap (everything else). // The main heap uses a different alignment. ReservedSpace perm_rs = heap_rs.first_part(pg_max_size); ReservedSpace main_rs = heap_rs.last_part(pg_max_size, og_align); // Make up the generations // Calculate the maximum size that a generation can grow. This // includes growth into the other generation. Note that the // parameter _max_gen_size is kept as the maximum // size of the generation as the boundaries currently stand. // _max_gen_size is still used as that value. double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0; double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0; _gens = new AdjoiningGenerations(main_rs, og_cur_size, og_min_size, og_max_size, yg_cur_size, yg_min_size, yg_max_size, yg_align); _old_gen = _gens->old_gen(); _young_gen = _gens->young_gen(); const size_t eden_capacity = _young_gen->eden_space()->capacity_in_bytes(); const size_t old_capacity = _old_gen->capacity_in_bytes(); const size_t initial_promo_size = MIN2(eden_capacity, old_capacity); _size_policy = new PSAdaptiveSizePolicy(eden_capacity, initial_promo_size, young_gen()->to_space()->capacity_in_bytes(), intra_heap_alignment(), max_gc_pause_sec, max_gc_minor_pause_sec, GCTimeRatio ); _perm_gen = new PSPermGen(perm_rs, pg_align, pg_cur_size, pg_cur_size, pg_max_size, "perm", 2); assert(!UseAdaptiveGCBoundary || (old_gen()->virtual_space()->high_boundary() == young_gen()->virtual_space()->low_boundary()), "Boundaries must meet"); // initialize the policy counters - 2 collectors, 3 generations _gc_policy_counters = new PSGCAdaptivePolicyCounters("ParScav:MSC", 2, 3, _size_policy); _psh = this; // Set up the GCTaskManager _gc_task_manager = GCTaskManager::create(ParallelGCThreads); if (UseParallelOldGC && !PSParallelCompact::initialize()) { return JNI_ENOMEM; } return JNI_OK; }
void ParallelScavengeHeap::initialize() { // Cannot be initialized until after the flags are parsed GenerationSizer flag_parser; const size_t alignment = min_alignment(); // Check alignments // NEEDS_CLEANUP The default TwoGenerationCollectorPolicy uses // NewRatio; it should check UseAdaptiveSizePolicy. Changes from // generationSizer could move to the common code. size_t young_size = align_size_up(flag_parser.young_gen_size(), alignment); size_t max_young_size = align_size_up(flag_parser.max_young_gen_size(), alignment); size_t old_size = align_size_up(flag_parser.old_gen_size(), alignment); size_t max_old_size = align_size_up(flag_parser.max_old_gen_size(), alignment); size_t perm_size = align_size_up(flag_parser.perm_gen_size(), alignment); size_t max_perm_size = align_size_up(flag_parser.max_perm_gen_size(), alignment); // Calculate the total size. size_t total_reserved = max_young_size + max_old_size + max_perm_size; if (UseISM || UsePermISM) { total_reserved = round_to(total_reserved, LargePageSizeInBytes); } ReservedSpace heap_rs(total_reserved, alignment, UseISM || UsePermISM); if (!heap_rs.is_reserved()) { vm_exit_during_initialization("Could not reserve enough space for " "object heap"); } _reserved = MemRegion((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size())); HeapWord* boundary = (HeapWord*)(heap_rs.base() + max_young_size); CardTableExtension* card_table_barrier_set = new CardTableExtension(_reserved, 3); _barrier_set = card_table_barrier_set; oopDesc::set_bs(_barrier_set); if (_barrier_set == NULL) { vm_exit_during_initialization("Could not reserve enough space for " "barrier set"); } // Initial young gen size is 4 Mb size_t init_young_size = align_size_up(4 * M, alignment); init_young_size = MAX2(MIN2(init_young_size, max_young_size), young_size); ReservedSpace generation_rs = heap_rs.first_part(max_young_size); _young_gen = new PSYoungGen(generation_rs, init_young_size, young_size, max_young_size); heap_rs = heap_rs.last_part(max_young_size); generation_rs = heap_rs.first_part(max_old_size); _old_gen = new PSOldGen(generation_rs, old_size, old_size, max_old_size, "old", 1); heap_rs = heap_rs.last_part(max_old_size); _perm_gen = new PSPermGen(heap_rs, perm_size, perm_size, max_perm_size, "perm", 2); _size_policy = new AdaptiveSizePolicy(young_gen()->eden_space()->capacity_in_bytes(), old_gen()->capacity_in_bytes(), young_gen()->to_space()->capacity_in_bytes(), max_young_size, max_old_size, alignment); // initialize the policy counters - 2 collectors, 3 generations _gc_policy_counters = new GCPolicyCounters(PERF_GC, "ParScav:MSC", 2, 3); }