--- old/src/hotspot/share/gc/shared/genCollectedHeap.cpp 2019-01-24 15:51:09.607432180 +0100 +++ new/src/hotspot/share/gc/shared/genCollectedHeap.cpp 2019-01-24 15:51:09.371432949 +0100 @@ -557,8 +557,6 @@ return; // GC is disabled (e.g. JNI GetXXXCritical operation) } - GCIdMark gc_id_mark; - const bool do_clear_all_soft_refs = clear_all_soft_refs || soft_ref_policy()->should_clear_all_soft_refs(); @@ -566,103 +564,108 @@ const size_t metadata_prev_used = MetaspaceUtils::used_bytes(); - print_heap_before_gc(); - { - FlagSetting fl(_is_gc_active, true); + FlagSetting fl(_is_gc_active, true); - bool complete = full && (max_generation == OldGen); - bool old_collects_young = complete && !ScavengeBeforeFullGC; - bool do_young_collection = !old_collects_young && _young_gen->should_collect(full, size, is_tlab); - - FormatBuffer<> gc_string("%s", "Pause "); - if (do_young_collection) { - gc_string.append("Young"); - } else { - gc_string.append("Full"); - } + bool complete = full && (max_generation == OldGen); + bool old_collects_young = complete && !ScavengeBeforeFullGC; + bool do_young_collection = !old_collects_young && _young_gen->should_collect(full, size, is_tlab); + + size_t young_prev_used = _young_gen->used(); + size_t old_prev_used = _old_gen->used(); + bool run_verification = total_collections() >= VerifyGCStartAt; + bool prepared_for_verification = false; + bool do_full_collection = false; + + if (do_young_collection) { + GCIdMark gc_id_mark; GCTraceCPUTime tcpu; - GCTraceTime(Info, gc) t(gc_string, NULL, gc_cause(), true); + GCTraceTime(Info, gc) t("Pause Young", NULL, gc_cause(), true); + + print_heap_before_gc(); + + if (run_verification && VerifyGCLevel <= 0 && VerifyBeforeGC) { + prepare_for_verify(); + prepared_for_verification = true; + } gc_prologue(complete); increment_total_collections(complete); - size_t young_prev_used = _young_gen->used(); - size_t old_prev_used = _old_gen->used(); + collect_generation(_young_gen, + full, + size, + is_tlab, + run_verification && VerifyGCLevel <= 0, + do_clear_all_soft_refs, + false); + + if (size > 0 && (!is_tlab || _young_gen->supports_tlab_allocation()) && + size * HeapWordSize <= _young_gen->unsafe_max_alloc_nogc()) { + // Allocation request was met by young GC. + size = 0; + } + + // Ask if young collection is enough. If so, do the final steps for young collection, + // and fallthrough to the end. + do_full_collection = should_do_full_collection(size, full, is_tlab, max_generation); + if (!do_full_collection) { + // Adjust generation sizes. + _young_gen->compute_new_size(); - bool run_verification = total_collections() >= VerifyGCStartAt; + print_heap_change(young_prev_used, old_prev_used); + MetaspaceUtils::print_metaspace_change(metadata_prev_used); - bool prepared_for_verification = false; - bool collected_old = false; + // Track memory usage and detect low memory after GC finishes + MemoryService::track_memory_usage(); - if (do_young_collection) { - if (run_verification && VerifyGCLevel <= 0 && VerifyBeforeGC) { - prepare_for_verify(); - prepared_for_verification = true; - } - - collect_generation(_young_gen, - full, - size, - is_tlab, - run_verification && VerifyGCLevel <= 0, - do_clear_all_soft_refs, - false); - - if (size > 0 && (!is_tlab || _young_gen->supports_tlab_allocation()) && - size * HeapWordSize <= _young_gen->unsafe_max_alloc_nogc()) { - // Allocation request was met by young GC. - size = 0; - } + gc_epilogue(complete); } - bool must_restore_marks_for_biased_locking = false; + print_heap_after_gc(); - if (max_generation == OldGen && _old_gen->should_collect(full, size, is_tlab)) { - if (!complete) { - // The full_collections increment was missed above. - increment_total_full_collections(); - } - - if (!prepared_for_verification && run_verification && - VerifyGCLevel <= 1 && VerifyBeforeGC) { - prepare_for_verify(); - } - - if (do_young_collection) { - // We did a young GC. Need a new GC id for the old GC. - GCIdMark gc_id_mark; - GCTraceTime(Info, gc) t("Pause Full", NULL, gc_cause(), true); - collect_generation(_old_gen, full, size, is_tlab, run_verification && VerifyGCLevel <= 1, do_clear_all_soft_refs, true); - } else { - // No young GC done. Use the same GC id as was set up earlier in this method. - collect_generation(_old_gen, full, size, is_tlab, run_verification && VerifyGCLevel <= 1, do_clear_all_soft_refs, true); - } + } else { + // No young collection, ask if we need to perform Full collection. + do_full_collection = should_do_full_collection(size, full, is_tlab, max_generation); + } - must_restore_marks_for_biased_locking = true; - collected_old = true; + if (do_full_collection) { + GCIdMark gc_id_mark; + GCTraceCPUTime tcpu; + GCTraceTime(Info, gc) t("Pause Full", NULL, gc_cause(), true); + + print_heap_before_gc(); + + if (!prepared_for_verification && run_verification && + VerifyGCLevel <= 1 && VerifyBeforeGC) { + prepare_for_verify(); + } + + if (!do_young_collection) { + gc_prologue(complete); + increment_total_collections(); } + increment_total_full_collections(); - // Update "complete" boolean wrt what actually transpired -- - // for instance, a promotion failure could have led to - // a whole heap collection. - complete = complete || collected_old; + collect_generation(_old_gen, + full, + size, + is_tlab, + run_verification && VerifyGCLevel <= 1, + do_clear_all_soft_refs, + true); // Adjust generation sizes. - if (collected_old) { - _old_gen->compute_new_size(); - } + _old_gen->compute_new_size(); _young_gen->compute_new_size(); - if (complete) { - // Delete metaspaces for unloaded class loaders and clean up loader_data graph - ClassLoaderDataGraph::purge(); - MetaspaceUtils::verify_metrics(); - // Resize the metaspace capacity after full collections - MetaspaceGC::compute_new_size(); - update_full_collections_completed(); - } + // Delete metaspaces for unloaded class loaders and clean up loader_data graph + ClassLoaderDataGraph::purge(); + MetaspaceUtils::verify_metrics(); + // Resize the metaspace capacity after full collections + MetaspaceGC::compute_new_size(); + update_full_collections_completed(); print_heap_change(young_prev_used, old_prev_used); MetaspaceUtils::print_metaspace_change(metadata_prev_used); @@ -672,18 +675,21 @@ gc_epilogue(complete); - if (must_restore_marks_for_biased_locking) { - BiasedLocking::restore_marks(); - } - } + BiasedLocking::restore_marks(); - print_heap_after_gc(); + print_heap_after_gc(); + } #ifdef TRACESPINNING ParallelTaskTerminator::print_termination_counts(); #endif } +bool GenCollectedHeap::should_do_full_collection(size_t size, bool full, bool is_tlab, + GenCollectedHeap::GenerationType max_gen) const { + return max_gen == OldGen && _old_gen->should_collect(full, size, is_tlab); +} + void GenCollectedHeap::register_nmethod(nmethod* nm) { CodeCache::register_scavenge_root_nmethod(nm); } --- old/src/hotspot/share/gc/shared/genCollectedHeap.hpp 2019-01-24 15:51:10.299429923 +0100 +++ new/src/hotspot/share/gc/shared/genCollectedHeap.hpp 2019-01-24 15:51:10.067430680 +0100 @@ -503,6 +503,10 @@ // Save the tops of the spaces in all generations void record_gen_tops_before_GC() PRODUCT_RETURN; + + // Return true if we need to perform full collection. + bool should_do_full_collection(size_t size, bool full, + bool is_tlab, GenerationType max_gen) const; }; #endif // SHARE_GC_SHARED_GENCOLLECTEDHEAP_HPP