changeset 57811:64a3594e98cc

8234440: ZGC: Print relocation information on info level Reviewed-by: stefank, eosterlund
author pliden
date Thu, 23 Jan 2020 15:13:32 +0100
parents 89e091daad39
children 34138fe5f9f7
files src/hotspot/share/gc/z/zHeap.cpp src/hotspot/share/gc/z/zRelocationSetSelector.cpp src/hotspot/share/gc/z/zRelocationSetSelector.hpp src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp src/hotspot/share/gc/z/zStat.cpp src/hotspot/share/gc/z/zStat.hpp
diffstat 6 files changed, 239 insertions(+), 87 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/gc/z/zHeap.cpp	Thu Jan 23 14:42:49 2020 +0100
+++ b/src/hotspot/share/gc/z/zHeap.cpp	Thu Jan 23 15:13:32 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,7 @@
 #include "gc/z/zPage.inline.hpp"
 #include "gc/z/zPageTable.inline.hpp"
 #include "gc/z/zRelocationSet.inline.hpp"
-#include "gc/z/zRelocationSetSelector.hpp"
+#include "gc/z/zRelocationSetSelector.inline.hpp"
 #include "gc/z/zResurrection.hpp"
 #include "gc/z/zStat.hpp"
 #include "gc/z/zThread.inline.hpp"
@@ -412,10 +412,8 @@
   }
 
   // Update statistics
-  ZStatRelocation::set_at_select_relocation_set(selector.relocating());
-  ZStatHeap::set_at_select_relocation_set(selector.live(),
-                                          selector.garbage(),
-                                          reclaimed());
+  ZStatRelocation::set_at_select_relocation_set(selector.stats());
+  ZStatHeap::set_at_select_relocation_set(selector.stats(), reclaimed());
 }
 
 void ZHeap::reset_relocation_set() {
--- a/src/hotspot/share/gc/z/zRelocationSetSelector.cpp	Thu Jan 23 14:42:49 2020 +0100
+++ b/src/hotspot/share/gc/z/zRelocationSetSelector.cpp	Thu Jan 23 15:13:32 2020 +0100
@@ -25,11 +25,20 @@
 #include "gc/z/zArray.inline.hpp"
 #include "gc/z/zPage.inline.hpp"
 #include "gc/z/zRelocationSet.hpp"
-#include "gc/z/zRelocationSetSelector.hpp"
+#include "gc/z/zRelocationSetSelector.inline.hpp"
 #include "logging/log.hpp"
 #include "runtime/globals.hpp"
 #include "utilities/debug.hpp"
 
+ZRelocationSetSelectorGroupStats::ZRelocationSetSelectorGroupStats() :
+    _npages(0),
+    _total(0),
+    _live(0),
+    _garbage(0),
+    _empty(0),
+    _compacting_from(0),
+    _compacting_to(0) {}
+
 ZRelocationSetSelectorGroup::ZRelocationSetSelectorGroup(const char* name,
                                                          size_t page_size,
                                                          size_t object_size_limit) :
@@ -40,16 +49,35 @@
     _registered_pages(),
     _sorted_pages(NULL),
     _nselected(0),
-    _relocating(0) {}
+    _stats() {}
 
 ZRelocationSetSelectorGroup::~ZRelocationSetSelectorGroup() {
   FREE_C_HEAP_ARRAY(ZPage*, _sorted_pages);
 }
 
-void ZRelocationSetSelectorGroup::register_live_page(ZPage* page, size_t garbage) {
+void ZRelocationSetSelectorGroup::register_live_page(ZPage* page) {
+  const uint8_t type = page->type();
+  const size_t size = page->size();
+  const size_t live = page->live_bytes();
+  const size_t garbage = size - live;
+
   if (garbage > _fragmentation_limit) {
     _registered_pages.add(page);
   }
+
+  _stats._npages++;
+  _stats._total += size;
+  _stats._live += live;
+  _stats._garbage += garbage;
+}
+
+void ZRelocationSetSelectorGroup::register_garbage_page(ZPage* page) {
+  const size_t size = page->size();
+
+  _stats._npages++;
+  _stats._total += size;
+  _stats._garbage += size;
+  _stats._empty += size;
 }
 
 void ZRelocationSetSelectorGroup::semi_sort() {
@@ -64,7 +92,8 @@
   size_t partitions[npartitions];
 
   // Allocate destination array
-  _sorted_pages = REALLOC_C_HEAP_ARRAY(ZPage*, _sorted_pages, npages, mtGC);
+  assert(_sorted_pages == NULL, "Already initialized");
+  _sorted_pages = NEW_C_HEAP_ARRAY(ZPage*, npages, mtGC);
   debug_only(memset(_sorted_pages, 0, npages * sizeof(ZPage*)));
 
   // Calculate partition slots
@@ -105,7 +134,6 @@
   const size_t npages = _registered_pages.size();
   size_t selected_from = 0;
   size_t selected_to = 0;
-  size_t selected_from_size = 0;
   size_t from_size = 0;
 
   semi_sort();
@@ -130,7 +158,6 @@
     if (diff_reclaimable > ZFragmentationLimit) {
       selected_from = from;
       selected_to = to;
-      selected_from_size = from_size;
     }
 
     log_trace(gc, reloc)("Candidate Relocation Set (%s Pages): "
@@ -140,47 +167,42 @@
 
   // Finalize selection
   _nselected = selected_from;
-  _relocating = selected_from_size;
-
-  log_debug(gc, reloc)("Relocation Set (%s Pages): " SIZE_FORMAT "->" SIZE_FORMAT ", " SIZE_FORMAT " skipped",
-                       _name, selected_from, selected_to, npages - _nselected);
-}
 
-ZPage* const* ZRelocationSetSelectorGroup::selected() const {
-  return _sorted_pages;
-}
+  // Update statistics
+  _stats._compacting_from = selected_from * _page_size;
+  _stats._compacting_to = selected_to * _page_size;
 
-size_t ZRelocationSetSelectorGroup::nselected() const {
-  return _nselected;
-}
-
-size_t ZRelocationSetSelectorGroup::relocating() const {
-  return _relocating;
+  log_trace(gc, reloc)("Relocation Set (%s Pages): " SIZE_FORMAT "->" SIZE_FORMAT ", " SIZE_FORMAT " skipped",
+                       _name, selected_from, selected_to, npages - _nselected);
 }
 
 ZRelocationSetSelector::ZRelocationSetSelector() :
     _small("Small", ZPageSizeSmall, ZObjectSizeLimitSmall),
     _medium("Medium", ZPageSizeMedium, ZObjectSizeLimitMedium),
-    _live(0),
-    _garbage(0) {}
+    _large("Large", 0 /* page_size */, 0 /* object_size_limit */) {}
 
 void ZRelocationSetSelector::register_live_page(ZPage* page) {
   const uint8_t type = page->type();
-  const size_t live = page->live_bytes();
-  const size_t garbage = page->size() - live;
 
   if (type == ZPageTypeSmall) {
-    _small.register_live_page(page, garbage);
+    _small.register_live_page(page);
   } else if (type == ZPageTypeMedium) {
-    _medium.register_live_page(page, garbage);
+    _medium.register_live_page(page);
+  } else {
+    _large.register_live_page(page);
   }
-
-  _live += live;
-  _garbage += garbage;
 }
 
 void ZRelocationSetSelector::register_garbage_page(ZPage* page) {
-  _garbage += page->size();
+  const uint8_t type = page->type();
+
+  if (type == ZPageTypeSmall) {
+    _small.register_garbage_page(page);
+  } else if (type == ZPageTypeMedium) {
+    _medium.register_garbage_page(page);
+  } else {
+    _large.register_garbage_page(page);
+  }
 }
 
 void ZRelocationSetSelector::select(ZRelocationSet* relocation_set) {
@@ -190,7 +212,7 @@
   // bytes in ascending order. Relocating pages in this order allows
   // us to start reclaiming memory more quickly.
 
-  // Select pages from each group
+  // Select pages from each group, except large
   _medium.select();
   _small.select();
 
@@ -199,14 +221,10 @@
                            _small.selected(), _small.nselected());
 }
 
-size_t ZRelocationSetSelector::live() const {
-  return _live;
+ZRelocationSetSelectorStats ZRelocationSetSelector::stats() const {
+  ZRelocationSetSelectorStats stats;
+  stats._small = _small.stats();
+  stats._medium = _medium.stats();
+  stats._large = _large.stats();
+  return stats;
 }
-
-size_t ZRelocationSetSelector::garbage() const {
-  return _garbage;
-}
-
-size_t ZRelocationSetSelector::relocating() const {
-  return _small.relocating() + _medium.relocating();
-}
--- a/src/hotspot/share/gc/z/zRelocationSetSelector.hpp	Thu Jan 23 14:42:49 2020 +0100
+++ b/src/hotspot/share/gc/z/zRelocationSetSelector.hpp	Thu Jan 23 15:13:32 2020 +0100
@@ -30,17 +30,55 @@
 class ZPage;
 class ZRelocationSet;
 
+class ZRelocationSetSelectorGroupStats {
+  friend class ZRelocationSetSelectorGroup;
+
+private:
+  size_t _npages;
+  size_t _total;
+  size_t _live;
+  size_t _garbage;
+  size_t _empty;
+  size_t _compacting_from;
+  size_t _compacting_to;
+
+public:
+  ZRelocationSetSelectorGroupStats();
+
+  size_t npages() const;
+  size_t total() const;
+  size_t live() const;
+  size_t garbage() const;
+  size_t empty() const;
+  size_t compacting_from() const;
+  size_t compacting_to() const;
+};
+
+class ZRelocationSetSelectorStats {
+  friend class ZRelocationSetSelector;
+
+private:
+  ZRelocationSetSelectorGroupStats _small;
+  ZRelocationSetSelectorGroupStats _medium;
+  ZRelocationSetSelectorGroupStats _large;
+
+public:
+  const ZRelocationSetSelectorGroupStats& small() const;
+  const ZRelocationSetSelectorGroupStats& medium() const;
+  const ZRelocationSetSelectorGroupStats& large() const;
+};
+
 class ZRelocationSetSelectorGroup {
 private:
-  const char* const _name;
-  const size_t      _page_size;
-  const size_t      _object_size_limit;
-  const size_t      _fragmentation_limit;
+  const char* const                _name;
+  const size_t                     _page_size;
+  const size_t                     _object_size_limit;
+  const size_t                     _fragmentation_limit;
 
-  ZArray<ZPage*>    _registered_pages;
-  ZPage**           _sorted_pages;
-  size_t            _nselected;
-  size_t            _relocating;
+  ZArray<ZPage*>                   _registered_pages;
+  ZPage**                          _sorted_pages;
+  size_t                           _nselected;
+  ZRelocationSetSelectorGroupStats _stats;
 
   void semi_sort();
 
@@ -50,20 +88,21 @@
                               size_t object_size_limit);
   ~ZRelocationSetSelectorGroup();
 
-  void register_live_page(ZPage* page, size_t garbage);
+  void register_live_page(ZPage* page);
+  void register_garbage_page(ZPage* page);
   void select();
 
   ZPage* const* selected() const;
   size_t nselected() const;
-  size_t relocating() const;
+
+  const ZRelocationSetSelectorGroupStats& stats() const;
 };
 
 class ZRelocationSetSelector : public StackObj {
 private:
   ZRelocationSetSelectorGroup _small;
   ZRelocationSetSelectorGroup _medium;
-  size_t                      _live;
-  size_t                      _garbage;
+  ZRelocationSetSelectorGroup _large;
 
 public:
   ZRelocationSetSelector();
@@ -72,9 +111,7 @@
   void register_garbage_page(ZPage* page);
   void select(ZRelocationSet* relocation_set);
 
-  size_t live() const;
-  size_t garbage() const;
-  size_t relocating() const;
+  ZRelocationSetSelectorStats stats() const;
 };
 
 #endif // SHARE_GC_Z_ZRELOCATIONSETSELECTOR_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp	Thu Jan 23 15:13:32 2020 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef SHARE_GC_Z_ZRELOCATIONSETSELECTOR_INLINE_HPP
+#define SHARE_GC_Z_ZRELOCATIONSETSELECTOR_INLINE_HPP
+
+#include "gc/z/zRelocationSetSelector.hpp"
+
+inline size_t ZRelocationSetSelectorGroupStats::npages() const {
+  return _npages;
+}
+
+inline size_t ZRelocationSetSelectorGroupStats::total() const {
+  return _total;
+}
+
+inline size_t ZRelocationSetSelectorGroupStats::live() const {
+  return _live;
+}
+
+inline size_t ZRelocationSetSelectorGroupStats::garbage() const {
+  return _garbage;
+}
+
+inline size_t ZRelocationSetSelectorGroupStats::empty() const {
+  return _empty;
+}
+
+inline size_t ZRelocationSetSelectorGroupStats::compacting_from() const {
+  return _compacting_from;
+}
+
+inline size_t ZRelocationSetSelectorGroupStats::compacting_to() const {
+  return _compacting_to;
+}
+
+inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorStats::small() const {
+  return _small;
+}
+
+inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorStats::medium() const {
+  return _medium;
+}
+
+inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorStats::large() const {
+  return _large;
+}
+
+inline ZPage* const* ZRelocationSetSelectorGroup::selected() const {
+  return _sorted_pages;
+}
+
+inline size_t ZRelocationSetSelectorGroup::nselected() const {
+  return _nselected;
+}
+
+inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorGroup::stats() const {
+  return _stats;
+}
+
+#endif // SHARE_GC_Z_ZRELOCATIONSETSELECTOR_INLINE_HPP
--- a/src/hotspot/share/gc/z/zStat.cpp	Thu Jan 23 14:42:49 2020 +0100
+++ b/src/hotspot/share/gc/z/zStat.cpp	Thu Jan 23 15:13:32 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
 #include "gc/z/zLargePages.inline.hpp"
 #include "gc/z/zNMethodTable.hpp"
 #include "gc/z/zNUMA.hpp"
+#include "gc/z/zRelocationSetSelector.inline.hpp"
 #include "gc/z/zStat.hpp"
 #include "gc/z/zTracer.inline.hpp"
 #include "gc/z/zUtils.hpp"
@@ -41,12 +42,13 @@
 #include "utilities/debug.hpp"
 #include "utilities/ticks.hpp"
 
-#define ZSIZE_FMT               SIZE_FORMAT "M(%.0f%%)"
-#define ZSIZE_ARGS(size)        ((size) / M), (percent_of(size, ZStatHeap::max_capacity()))
+#define ZSIZE_FMT                       SIZE_FORMAT "M(%.0f%%)"
+#define ZSIZE_ARGS_WITH_MAX(size, max)  ((size) / M), (percent_of(size, max))
+#define ZSIZE_ARGS(size)                ZSIZE_ARGS_WITH_MAX(size, ZStatHeap::max_capacity())
 
-#define ZTABLE_ARGS_NA          "%9s", "-"
-#define ZTABLE_ARGS(size)       SIZE_FORMAT_W(8) "M (%.0f%%)", \
-                                ((size) / M), (percent_of(size, ZStatHeap::max_capacity()))
+#define ZTABLE_ARGS_NA                  "%9s", "-"
+#define ZTABLE_ARGS(size)               SIZE_FORMAT_W(8) "M (%.0f%%)", \
+                                        ((size) / M), (percent_of(size, ZStatHeap::max_capacity()))
 
 //
 // Stat sampler/counter data
@@ -641,10 +643,10 @@
   ZStatLoad::print();
   ZStatMMU::print();
   ZStatMark::print();
-  ZStatRelocation::print();
   ZStatNMethods::print();
   ZStatMetaspace::print();
   ZStatReferences::print();
+  ZStatRelocation::print();
   ZStatHeap::print();
 
   log_info(gc)("Garbage Collection (%s) " ZSIZE_FMT "->" ZSIZE_FMT,
@@ -1126,23 +1128,35 @@
 //
 // Stat relocation
 //
-size_t ZStatRelocation::_relocating;
-bool ZStatRelocation::_success;
+ZRelocationSetSelectorStats ZStatRelocation::_stats;
+bool                        ZStatRelocation::_success;
 
-void ZStatRelocation::set_at_select_relocation_set(size_t relocating) {
-  _relocating = relocating;
+void ZStatRelocation::set_at_select_relocation_set(const ZRelocationSetSelectorStats& stats) {
+  _stats = stats;
 }
 
 void ZStatRelocation::set_at_relocate_end(bool success) {
   _success = success;
 }
 
+void ZStatRelocation::print(const char* name, const ZRelocationSetSelectorGroupStats& group) {
+  const size_t total = _stats.small().total() + _stats.medium().total() + _stats.large().total();
+
+  log_info(gc, reloc)("%s Pages: " SIZE_FORMAT " / " ZSIZE_FMT ", Empty: " ZSIZE_FMT ", Compacting: " ZSIZE_FMT "->" ZSIZE_FMT,
+                      name,
+                      group.npages(),
+                      ZSIZE_ARGS_WITH_MAX(group.total(), total),
+                      ZSIZE_ARGS_WITH_MAX(group.empty(), total),
+                      ZSIZE_ARGS_WITH_MAX(group.compacting_from(), total),
+                      ZSIZE_ARGS_WITH_MAX(group.compacting_to(), total));
+}
+
 void ZStatRelocation::print() {
-  if (_success) {
-    log_info(gc, reloc)("Relocation: Successful, " SIZE_FORMAT "M relocated", _relocating / M);
-  } else {
-    log_info(gc, reloc)("Relocation: Incomplete");
-  }
+  print("Small", _stats.small());
+  print("Medium", _stats.medium());
+  print("Large", _stats.large());
+
+  log_info(gc, reloc)("Relocation: %s", _success ? "Successful" : "Incomplete");
 }
 
 //
@@ -1278,9 +1292,10 @@
   _at_mark_end.free = free(used);
 }
 
-void ZStatHeap::set_at_select_relocation_set(size_t live,
-                                             size_t garbage,
-                                             size_t reclaimed) {
+void ZStatHeap::set_at_select_relocation_set(const ZRelocationSetSelectorStats& stats, size_t reclaimed) {
+  const size_t live = stats.small().live() + stats.medium().live() + stats.large().live();
+  const size_t garbage = stats.small().garbage() + stats.medium().garbage() + stats.large().garbage();
+
   _at_mark_end.live = live;
   _at_mark_end.garbage = garbage;
 
--- a/src/hotspot/share/gc/z/zStat.hpp	Thu Jan 23 14:42:49 2020 +0100
+++ b/src/hotspot/share/gc/z/zStat.hpp	Thu Jan 23 15:13:32 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,8 @@
 #include "utilities/ticks.hpp"
 
 class ZPage;
+class ZRelocationSetSelectorGroupStats;
+class ZRelocationSetSelectorStats;
 class ZStatSampler;
 class ZStatSamplerHistory;
 struct ZStatCounterData;
@@ -418,11 +420,13 @@
 //
 class ZStatRelocation : public AllStatic {
 private:
-  static size_t _relocating;
-  static bool   _success;
+  static ZRelocationSetSelectorStats _stats;
+  static bool                        _success;
+
+  static void print(const char* name, const ZRelocationSetSelectorGroupStats& group);
 
 public:
-  static void set_at_select_relocation_set(size_t relocating);
+  static void set_at_select_relocation_set(const ZRelocationSetSelectorStats& stats);
   static void set_at_relocate_end(bool success);
 
   static void print();
@@ -540,8 +544,7 @@
   static void set_at_mark_end(size_t capacity,
                               size_t allocated,
                               size_t used);
-  static void set_at_select_relocation_set(size_t live,
-                                           size_t garbage,
+  static void set_at_select_relocation_set(const ZRelocationSetSelectorStats& stats,
                                            size_t reclaimed);
   static void set_at_relocate_start(size_t capacity,
                                     size_t allocated,