< prev index next >

src/hotspot/share/gc/shared/genCollectedHeap.cpp

Print this page
rev 53464 : 8215221: Serial GC misreports young GC time
Reviewed-by: XXX

@@ -555,55 +555,46 @@
 
   if (GCLocker::check_active_before_gc()) {
     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();
 
   ClearedAllSoftRefs casr(do_clear_all_soft_refs, soft_ref_policy());
 
   const size_t metadata_prev_used = MetaspaceUtils::used_bytes();
 
-  print_heap_before_gc();
 
-  {
     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");
-    }
-
-    GCTraceCPUTime tcpu;
-    GCTraceTime(Info, gc) t(gc_string, NULL, gc_cause(), true);
-
-    gc_prologue(complete);
-    increment_total_collections(complete);
-
     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 collected_old = false;
+  bool do_full_collection = false;
 
     if (do_young_collection) {
+    GCIdMark gc_id_mark;
+    GCTraceCPUTime tcpu;
+    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);
+
       collect_generation(_young_gen,
                          full,
                          size,
                          is_tlab,
                          run_verification && VerifyGCLevel <= 0,

@@ -613,79 +604,94 @@
       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;
       }
-    }
 
-    bool must_restore_marks_for_biased_locking = false;
+    // 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();
 
-    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();
+      print_heap_change(young_prev_used, old_prev_used);
+      MetaspaceUtils::print_metaspace_change(metadata_prev_used);
+
+      // Track memory usage and detect low memory after GC finishes
+      MemoryService::track_memory_usage();
+
+      gc_epilogue(complete);
       }
 
-      if (!prepared_for_verification && run_verification &&
-          VerifyGCLevel <= 1 && VerifyBeforeGC) {
-        prepare_for_verify();
+    print_heap_after_gc();
+
+  } 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);
       }
 
-      if (do_young_collection) {
-        // We did a young GC. Need a new GC id for the old GC.
+  if (do_full_collection) {
         GCIdMark gc_id_mark;
+    GCTraceCPUTime tcpu;
         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);
+
+    print_heap_before_gc();
+
+    if (!prepared_for_verification && run_verification &&
+        VerifyGCLevel <= 1 && VerifyBeforeGC) {
+      prepare_for_verify();
       }
 
-      must_restore_marks_for_biased_locking = true;
-      collected_old = true;
+    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();
-    }
     _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();
-    }
 
     print_heap_change(young_prev_used, old_prev_used);
     MetaspaceUtils::print_metaspace_change(metadata_prev_used);
 
     // Track memory usage and detect low memory after GC finishes
     MemoryService::track_memory_usage();
 
     gc_epilogue(complete);
 
-    if (must_restore_marks_for_biased_locking) {
       BiasedLocking::restore_marks();
-    }
-  }
 
   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);
 }
 
 void GenCollectedHeap::verify_nmethod(nmethod* nm) {
< prev index next >