changeset 48043:cb5d2d4453d0

8191564: Refactor GC related servicability code into GC specific subclasses Reviewed-by: ehelin, eosterlund
author rkennke
date Thu, 30 Nov 2017 13:40:07 +0100
parents f04a848c6f00
children 9289fcb41aae
files src/hotspot/share/gc/cms/cmsHeap.cpp src/hotspot/share/gc/cms/cmsHeap.hpp src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp src/hotspot/share/gc/g1/g1CollectedHeap.cpp src/hotspot/share/gc/g1/g1CollectedHeap.hpp src/hotspot/share/gc/g1/g1FullCollector.cpp src/hotspot/share/gc/g1/g1FullCollector.hpp src/hotspot/share/gc/g1/g1FullGCScope.cpp src/hotspot/share/gc/g1/g1FullGCScope.hpp src/hotspot/share/gc/g1/g1MemoryPool.cpp src/hotspot/share/gc/g1/g1MemoryPool.hpp src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp src/hotspot/share/gc/parallel/psMarkSweep.cpp src/hotspot/share/gc/parallel/psMemoryPool.cpp src/hotspot/share/gc/parallel/psMemoryPool.hpp src/hotspot/share/gc/parallel/psParallelCompact.cpp src/hotspot/share/gc/parallel/psScavenge.cpp src/hotspot/share/gc/serial/serialHeap.cpp src/hotspot/share/gc/serial/serialHeap.hpp src/hotspot/share/gc/shared/collectedHeap.cpp src/hotspot/share/gc/shared/collectedHeap.hpp src/hotspot/share/gc/shared/genCollectedHeap.cpp src/hotspot/share/gc/shared/genCollectedHeap.hpp src/hotspot/share/gc/shared/genMemoryPools.cpp src/hotspot/share/gc/shared/genMemoryPools.hpp src/hotspot/share/gc/shared/generation.cpp src/hotspot/share/gc/shared/generation.hpp src/hotspot/share/services/g1MemoryPool.cpp src/hotspot/share/services/g1MemoryPool.hpp src/hotspot/share/services/memoryManager.cpp src/hotspot/share/services/memoryManager.hpp src/hotspot/share/services/memoryPool.cpp src/hotspot/share/services/memoryPool.hpp src/hotspot/share/services/memoryService.cpp src/hotspot/share/services/memoryService.hpp src/hotspot/share/services/psMemoryPool.cpp src/hotspot/share/services/psMemoryPool.hpp test/hotspot/jtreg/gc/TestMemoryMXBeansAndPoolsPresence.java
diffstat 39 files changed, 1033 insertions(+), 1172 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/gc/cms/cmsHeap.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/cms/cmsHeap.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -23,17 +23,48 @@
  */
 
 #include "precompiled.hpp"
+#include "gc/cms/compactibleFreeListSpace.hpp"
+#include "gc/cms/concurrentMarkSweepGeneration.hpp"
 #include "gc/cms/concurrentMarkSweepThread.hpp"
 #include "gc/cms/cmsHeap.hpp"
+#include "gc/cms/parNewGeneration.hpp"
 #include "gc/cms/vmCMSOperations.hpp"
+#include "gc/shared/genMemoryPools.hpp"
 #include "gc/shared/genOopClosures.inline.hpp"
 #include "gc/shared/strongRootsScope.hpp"
 #include "gc/shared/workgroup.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/vmThread.hpp"
+#include "services/memoryManager.hpp"
 #include "utilities/stack.inline.hpp"
 
-CMSHeap::CMSHeap(GenCollectorPolicy *policy) : GenCollectedHeap(policy) {
+class CompactibleFreeListSpacePool : public CollectedMemoryPool {
+private:
+  CompactibleFreeListSpace* _space;
+public:
+  CompactibleFreeListSpacePool(CompactibleFreeListSpace* space,
+                               const char* name,
+                               size_t max_size,
+                               bool support_usage_threshold) :
+    CollectedMemoryPool(name, space->capacity(), max_size, support_usage_threshold),
+    _space(space) {
+  }
+
+  MemoryUsage get_memory_usage() {
+    size_t max_heap_size   = (available_for_allocation() ? max_size() : 0);
+    size_t used      = used_in_bytes();
+    size_t committed = _space->capacity();
+
+    return MemoryUsage(initial_size(), used, committed, max_heap_size);
+  }
+
+  size_t used_in_bytes() {
+    return _space->used();
+  }
+};
+
+CMSHeap::CMSHeap(GenCollectorPolicy *policy) :
+  GenCollectedHeap(policy), _eden_pool(NULL), _survivor_pool(NULL), _old_pool(NULL) {
   _workers = new WorkGang("GC Thread", ParallelGCThreads,
                           /* are_GC_task_threads */true,
                           /* are_ConcurrentGC_threads */false);
@@ -54,6 +85,38 @@
   return JNI_OK;
 }
 
+void CMSHeap::initialize_serviceability() {
+  _young_manager = new GCMemoryManager("ParNew", "end of minor GC");
+  _old_manager = new GCMemoryManager("ConcurrentMarkSweep", "end of major GC");
+
+  ParNewGeneration* young = (ParNewGeneration*) young_gen();
+  _eden_pool = new ContiguousSpacePool(young->eden(),
+                                       "Par Eden Space",
+                                       young->max_eden_size(),
+                                       false);
+
+  _survivor_pool = new SurvivorContiguousSpacePool(young,
+                                                   "Par Survivor Space",
+                                                   young->max_survivor_size(),
+                                                   false);
+
+  ConcurrentMarkSweepGeneration* old = (ConcurrentMarkSweepGeneration*) old_gen();
+  _old_pool = new CompactibleFreeListSpacePool(old->cmsSpace(),
+                                               "CMS Old Gen",
+                                               old->reserved().byte_size(),
+                                               true);
+
+  _young_manager->add_pool(_eden_pool);
+  _young_manager->add_pool(_survivor_pool);
+  young->set_gc_manager(_young_manager);
+
+  _old_manager->add_pool(_eden_pool);
+  _old_manager->add_pool(_survivor_pool);
+  _old_manager->add_pool(_old_pool);
+  old ->set_gc_manager(_old_manager);
+
+}
+
 void CMSHeap::check_gen_kinds() {
   assert(young_gen()->kind() == Generation::ParNew,
          "Wrong youngest generation type");
@@ -183,3 +246,18 @@
   GenCollectedHeap::gc_epilogue(full);
   always_do_update_barrier = true;
 };
+
+GrowableArray<GCMemoryManager*> CMSHeap::memory_managers() {
+  GrowableArray<GCMemoryManager*> memory_managers(2);
+  memory_managers.append(_young_manager);
+  memory_managers.append(_old_manager);
+  return memory_managers;
+}
+
+GrowableArray<MemoryPool*> CMSHeap::memory_pools() {
+  GrowableArray<MemoryPool*> memory_pools(3);
+  memory_pools.append(_eden_pool);
+  memory_pools.append(_survivor_pool);
+  memory_pools.append(_old_pool);
+  return memory_pools;
+}
--- a/src/hotspot/share/gc/cms/cmsHeap.hpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/cms/cmsHeap.hpp	Thu Nov 30 13:40:07 2017 +0100
@@ -29,9 +29,12 @@
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/gcCause.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
+#include "utilities/growableArray.hpp"
 
 class CLDClosure;
 class GenCollectorPolicy;
+class GCMemoryManager;
+class MemoryPool;
 class OopsInGenClosure;
 class outputStream;
 class StrongRootsScope;
@@ -80,6 +83,9 @@
   void safepoint_synchronize_begin();
   void safepoint_synchronize_end();
 
+  virtual GrowableArray<GCMemoryManager*> memory_managers();
+  virtual GrowableArray<MemoryPool*> memory_pools();
+
   // If "young_gen_as_roots" is false, younger generations are
   // not scanned as roots; in this case, the caller must be arranging to
   // scan the younger generations itself.  (For example, a generation might
@@ -92,12 +98,19 @@
                          OopsInGenClosure* root_closure,
                          CLDClosure* cld_closure);
 
+  GCMemoryManager* old_manager() const { return _old_manager; }
+
 private:
   WorkGang* _workers;
+  MemoryPool* _eden_pool;
+  MemoryPool* _survivor_pool;
+  MemoryPool* _old_pool;
 
   virtual void gc_prologue(bool full);
   virtual void gc_epilogue(bool full);
 
+  virtual void initialize_serviceability();
+
   // Accessor for memory state verification support
   NOT_PRODUCT(
     virtual size_t skip_header_HeapWords() { return CMSCollector::skip_header_HeapWords(); }
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -8116,42 +8116,42 @@
 }
 
 TraceCMSMemoryManagerStats::TraceCMSMemoryManagerStats(CMSCollector::CollectorState phase, GCCause::Cause cause): TraceMemoryManagerStats() {
-
+  GCMemoryManager* manager = CMSHeap::heap()->old_manager();
   switch (phase) {
     case CMSCollector::InitialMarking:
-      initialize(true  /* fullGC */ ,
-                 cause /* cause of the GC */,
-                 true  /* recordGCBeginTime */,
-                 true  /* recordPreGCUsage */,
-                 false /* recordPeakUsage */,
-                 false /* recordPostGCusage */,
-                 true  /* recordAccumulatedGCTime */,
-                 false /* recordGCEndTime */,
-                 false /* countCollection */  );
+      initialize(manager /* GC manager */ ,
+                 cause   /* cause of the GC */,
+                 true    /* recordGCBeginTime */,
+                 true    /* recordPreGCUsage */,
+                 false   /* recordPeakUsage */,
+                 false   /* recordPostGCusage */,
+                 true    /* recordAccumulatedGCTime */,
+                 false   /* recordGCEndTime */,
+                 false   /* countCollection */  );
       break;
 
     case CMSCollector::FinalMarking:
-      initialize(true  /* fullGC */ ,
-                 cause /* cause of the GC */,
-                 false /* recordGCBeginTime */,
-                 false /* recordPreGCUsage */,
-                 false /* recordPeakUsage */,
-                 false /* recordPostGCusage */,
-                 true  /* recordAccumulatedGCTime */,
-                 false /* recordGCEndTime */,
-                 false /* countCollection */  );
+      initialize(manager /* GC manager */ ,
+                 cause   /* cause of the GC */,
+                 false   /* recordGCBeginTime */,
+                 false   /* recordPreGCUsage */,
+                 false   /* recordPeakUsage */,
+                 false   /* recordPostGCusage */,
+                 true    /* recordAccumulatedGCTime */,
+                 false   /* recordGCEndTime */,
+                 false   /* countCollection */  );
       break;
 
     case CMSCollector::Sweeping:
-      initialize(true  /* fullGC */ ,
-                 cause /* cause of the GC */,
-                 false /* recordGCBeginTime */,
-                 false /* recordPreGCUsage */,
-                 true  /* recordPeakUsage */,
-                 true  /* recordPostGCusage */,
-                 false /* recordAccumulatedGCTime */,
-                 true  /* recordGCEndTime */,
-                 true  /* countCollection */  );
+      initialize(manager /* GC manager */ ,
+                 cause   /* cause of the GC */,
+                 false   /* recordGCBeginTime */,
+                 false   /* recordPreGCUsage */,
+                 true    /* recordPeakUsage */,
+                 true    /* recordPostGCusage */,
+                 false   /* recordAccumulatedGCTime */,
+                 true    /* recordGCEndTime */,
+                 true    /* countCollection */  );
       break;
 
     default:
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -44,6 +44,7 @@
 #include "gc/g1/g1HeapTransition.hpp"
 #include "gc/g1/g1HeapVerifier.hpp"
 #include "gc/g1/g1HotCardCache.hpp"
+#include "gc/g1/g1MemoryPool.hpp"
 #include "gc/g1/g1OopClosures.inline.hpp"
 #include "gc/g1/g1ParScanThreadState.inline.hpp"
 #include "gc/g1/g1Policy.hpp"
@@ -1229,7 +1230,7 @@
   const bool do_clear_all_soft_refs = clear_all_soft_refs ||
       collector_policy()->should_clear_all_soft_refs();
 
-  G1FullCollector collector(this, explicit_gc, do_clear_all_soft_refs);
+  G1FullCollector collector(this, &_full_gc_memory_manager, explicit_gc, do_clear_all_soft_refs);
   GCTraceTime(Info, gc) tm("Pause Full", NULL, gc_cause(), true);
 
   collector.prepare_collection();
@@ -1526,6 +1527,11 @@
   CollectedHeap(),
   _young_gen_sampling_thread(NULL),
   _collector_policy(collector_policy),
+  _memory_manager("G1 Young Generation", "end of minor GC"),
+  _full_gc_memory_manager("G1 Old Generation", "end of major GC"),
+  _eden_pool(NULL),
+  _survivor_pool(NULL),
+  _old_pool(NULL),
   _gc_timer_stw(new (ResourceObj::C_HEAP, mtGC) STWGCTimer()),
   _gc_tracer_stw(new (ResourceObj::C_HEAP, mtGC) G1NewTracer()),
   _g1_policy(create_g1_policy(_gc_timer_stw)),
@@ -1830,6 +1836,20 @@
   return JNI_OK;
 }
 
+void G1CollectedHeap::initialize_serviceability() {
+  _eden_pool = new G1EdenPool(this);
+  _survivor_pool = new G1SurvivorPool(this);
+  _old_pool = new G1OldGenPool(this);
+
+  _full_gc_memory_manager.add_pool(_eden_pool);
+  _full_gc_memory_manager.add_pool(_survivor_pool);
+  _full_gc_memory_manager.add_pool(_old_pool);
+
+  _memory_manager.add_pool(_eden_pool);
+  _memory_manager.add_pool(_survivor_pool);
+
+}
+
 void G1CollectedHeap::stop() {
   // Stop all concurrent threads. We do this to make sure these threads
   // do not continue to execute and access resources (e.g. logging)
@@ -1855,6 +1875,7 @@
 }
 
 void G1CollectedHeap::post_initialize() {
+  CollectedHeap::post_initialize();
   ref_processing_init();
 }
 
@@ -2954,7 +2975,7 @@
     log_info(gc,task)("Using %u workers of %u for evacuation", active_workers, workers()->total_workers());
 
     TraceCollectorStats tcs(g1mm()->incremental_collection_counters());
-    TraceMemoryManagerStats tms(false /* fullGC */, gc_cause());
+    TraceMemoryManagerStats tms(&_memory_manager, gc_cause());
 
     // If the secondary_free_list is not empty, append it to the
     // free_list. No need to wait for the cleanup operation to finish;
@@ -5368,3 +5389,18 @@
   RebuildStrongCodeRootClosure blob_cl(this);
   CodeCache::blobs_do(&blob_cl);
 }
+
+GrowableArray<GCMemoryManager*> G1CollectedHeap::memory_managers() {
+  GrowableArray<GCMemoryManager*> memory_managers(2);
+  memory_managers.append(&_memory_manager);
+  memory_managers.append(&_full_gc_memory_manager);
+  return memory_managers;
+}
+
+GrowableArray<MemoryPool*> G1CollectedHeap::memory_pools() {
+  GrowableArray<MemoryPool*> memory_pools(3);
+  memory_pools.append(_eden_pool);
+  memory_pools.append(_survivor_pool);
+  memory_pools.append(_old_pool);
+  return memory_pools;
+}
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Thu Nov 30 13:40:07 2017 +0100
@@ -50,6 +50,7 @@
 #include "gc/shared/plab.hpp"
 #include "gc/shared/preservedMarks.hpp"
 #include "memory/memRegion.hpp"
+#include "services/memoryManager.hpp"
 #include "utilities/stack.hpp"
 
 // A "G1CollectedHeap" is an implementation of a java heap for HotSpot.
@@ -64,6 +65,7 @@
 class G1ParScanThreadState;
 class G1ParScanThreadStateSet;
 class G1ParScanThreadState;
+class MemoryPool;
 class ObjectClosure;
 class SpaceClosure;
 class CompactibleSpaceClosure;
@@ -149,6 +151,13 @@
   WorkGang* _workers;
   G1CollectorPolicy* _collector_policy;
 
+  GCMemoryManager _memory_manager;
+  GCMemoryManager _full_gc_memory_manager;
+
+  MemoryPool* _eden_pool;
+  MemoryPool* _survivor_pool;
+  MemoryPool* _old_pool;
+
   static size_t _humongous_object_threshold_in_words;
 
   // The secondary free list which contains regions that have been
@@ -162,6 +171,8 @@
   // It keeps track of the humongous regions.
   HeapRegionSet _humongous_set;
 
+  virtual void initialize_serviceability();
+
   void eagerly_reclaim_humongous_regions();
   // Start a new incremental collection set for the next pause.
   void start_new_collection_set();
@@ -1006,6 +1017,9 @@
   // Adaptive size policy.  No such thing for g1.
   virtual AdaptiveSizePolicy* size_policy() { return NULL; }
 
+  virtual GrowableArray<GCMemoryManager*> memory_managers();
+  virtual GrowableArray<MemoryPool*> memory_pools();
+
   // The rem set and barrier set.
   G1RemSet* g1_rem_set() const { return _g1_rem_set; }
 
--- a/src/hotspot/share/gc/g1/g1FullCollector.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -71,9 +71,9 @@
   return _heap->ref_processor_stw();
 }
 
-G1FullCollector::G1FullCollector(G1CollectedHeap* heap, bool explicit_gc, bool clear_soft_refs) :
+G1FullCollector::G1FullCollector(G1CollectedHeap* heap, GCMemoryManager* memory_manager, bool explicit_gc, bool clear_soft_refs) :
     _heap(heap),
-    _scope(explicit_gc, clear_soft_refs),
+    _scope(memory_manager, explicit_gc, clear_soft_refs),
     _num_workers(heap->workers()->active_workers()),
     _oop_queue_set(_num_workers),
     _array_queue_set(_num_workers),
--- a/src/hotspot/share/gc/g1/g1FullCollector.hpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/g1/g1FullCollector.hpp	Thu Nov 30 13:40:07 2017 +0100
@@ -39,6 +39,7 @@
 class G1FullGCMarker;
 class G1FullGCScope;
 class G1FullGCCompactionPoint;
+class GCMemoryManager;
 class ReferenceProcessor;
 
 // The G1FullCollector holds data associated with the current Full GC.
@@ -56,7 +57,7 @@
   ReferenceProcessorIsAliveMutator _is_alive_mutator;
 
 public:
-  G1FullCollector(G1CollectedHeap* heap, bool explicit_gc, bool clear_soft_refs);
+  G1FullCollector(G1CollectedHeap* heap, GCMemoryManager* memory_manager, bool explicit_gc, bool clear_soft_refs);
   ~G1FullCollector();
 
   void prepare_collection();
--- a/src/hotspot/share/gc/g1/g1FullGCScope.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/g1/g1FullGCScope.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -25,7 +25,7 @@
 #include "precompiled.hpp"
 #include "gc/g1/g1FullGCScope.hpp"
 
-G1FullGCScope::G1FullGCScope(bool explicit_gc, bool clear_soft) :
+G1FullGCScope::G1FullGCScope(GCMemoryManager* memory_manager, bool explicit_gc, bool clear_soft) :
     _rm(),
     _explicit_gc(explicit_gc),
     _g1h(G1CollectedHeap::heap()),
@@ -36,7 +36,7 @@
     _active(),
     _cpu_time(),
     _soft_refs(clear_soft, _g1h->collector_policy()),
-    _memory_stats(true, _g1h->gc_cause()),
+    _memory_stats(memory_manager, _g1h->gc_cause()),
     _collector_stats(_g1h->g1mm()->full_collection_counters()),
     _heap_transition(_g1h) {
   _timer.register_gc_start();
--- a/src/hotspot/share/gc/g1/g1FullGCScope.hpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/g1/g1FullGCScope.hpp	Thu Nov 30 13:40:07 2017 +0100
@@ -37,6 +37,8 @@
 #include "memory/allocation.hpp"
 #include "services/memoryService.hpp"
 
+class GCMemoryManager;
+
 // Class used to group scoped objects used in the Full GC together.
 class G1FullGCScope : public StackObj {
   ResourceMark            _rm;
@@ -54,7 +56,7 @@
   G1HeapTransition        _heap_transition;
 
 public:
-  G1FullGCScope(bool explicit_gc, bool clear_soft);
+  G1FullGCScope(GCMemoryManager* memory_manager, bool explicit_gc, bool clear_soft);
   ~G1FullGCScope();
 
   bool is_explicit_gc();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1MemoryPool.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2007, 2017, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1CollectedHeap.hpp"
+#include "gc/g1/g1MemoryPool.hpp"
+#include "gc/g1/heapRegion.hpp"
+
+G1MemoryPoolSuper::G1MemoryPoolSuper(G1CollectedHeap* g1h,
+                                     const char* name,
+                                     size_t init_size,
+                                     size_t max_size,
+                                     bool support_usage_threshold) :
+  _g1mm(g1h->g1mm()), CollectedMemoryPool(name,
+                                          init_size,
+                                          max_size,
+                                          support_usage_threshold) {
+  assert(UseG1GC, "sanity");
+}
+
+G1EdenPool::G1EdenPool(G1CollectedHeap* g1h) :
+  G1MemoryPoolSuper(g1h,
+                    "G1 Eden Space",
+                    g1h->g1mm()->eden_space_committed(), /* init_size */
+                    _undefined_max,
+                    false /* support_usage_threshold */) { }
+
+MemoryUsage G1EdenPool::get_memory_usage() {
+  size_t initial_sz = initial_size();
+  size_t max_sz     = max_size();
+  size_t used       = used_in_bytes();
+  size_t committed  = _g1mm->eden_space_committed();
+
+  return MemoryUsage(initial_sz, used, committed, max_sz);
+}
+
+G1SurvivorPool::G1SurvivorPool(G1CollectedHeap* g1h) :
+  G1MemoryPoolSuper(g1h,
+                    "G1 Survivor Space",
+                    g1h->g1mm()->survivor_space_committed(), /* init_size */
+                    _undefined_max,
+                    false /* support_usage_threshold */) { }
+
+MemoryUsage G1SurvivorPool::get_memory_usage() {
+  size_t initial_sz = initial_size();
+  size_t max_sz     = max_size();
+  size_t used       = used_in_bytes();
+  size_t committed  = _g1mm->survivor_space_committed();
+
+  return MemoryUsage(initial_sz, used, committed, max_sz);
+}
+
+G1OldGenPool::G1OldGenPool(G1CollectedHeap* g1h) :
+  G1MemoryPoolSuper(g1h,
+                    "G1 Old Gen",
+                    g1h->g1mm()->old_space_committed(), /* init_size */
+                    g1h->g1mm()->old_gen_max(),
+                    true /* support_usage_threshold */) { }
+
+MemoryUsage G1OldGenPool::get_memory_usage() {
+  size_t initial_sz = initial_size();
+  size_t max_sz     = max_size();
+  size_t used       = used_in_bytes();
+  size_t committed  = _g1mm->old_space_committed();
+
+  return MemoryUsage(initial_sz, used, committed, max_sz);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1MemoryPool.hpp	Thu Nov 30 13:40:07 2017 +0100
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2007, 2017, 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_VM_GC_G1_G1MEMORYPOOL_HPP
+#define SHARE_VM_GC_G1_G1MEMORYPOOL_HPP
+
+#include "gc/g1/g1MonitoringSupport.hpp"
+#include "services/memoryPool.hpp"
+#include "services/memoryUsage.hpp"
+
+// This file contains the three classes that represent the memory
+// pools of the G1 spaces: G1EdenPool, G1SurvivorPool, and
+// G1OldGenPool. In G1, unlike our other GCs, we do not have a
+// physical space for each of those spaces. Instead, we allocate
+// regions for all three spaces out of a single pool of regions (that
+// pool basically covers the entire heap). As a result, the eden,
+// survivor, and old gen are considered logical spaces in G1, as each
+// is a set of non-contiguous regions. This is also reflected in the
+// way we map them to memory pools here. The easiest way to have done
+// this would have been to map the entire G1 heap to a single memory
+// pool. However, it's helpful to show how large the eden and survivor
+// get, as this does affect the performance and behavior of G1. Which
+// is why we introduce the three memory pools implemented here.
+//
+// See comments in g1MonitoringSupport.hpp for additional details
+// on this model.
+//
+
+class G1CollectedHeap;
+
+// This class is shared by the three G1 memory pool classes
+// (G1EdenPool, G1SurvivorPool, G1OldGenPool).
+class G1MemoryPoolSuper : public CollectedMemoryPool {
+protected:
+  const static size_t _undefined_max = (size_t) -1;
+  G1MonitoringSupport* _g1mm;
+
+  // Would only be called from subclasses.
+  G1MemoryPoolSuper(G1CollectedHeap* g1h,
+                    const char* name,
+                    size_t init_size,
+                    size_t max_size,
+                    bool support_usage_threshold);
+};
+
+// Memory pool that represents the G1 eden.
+class G1EdenPool : public G1MemoryPoolSuper {
+public:
+  G1EdenPool(G1CollectedHeap* g1h);
+
+  size_t used_in_bytes() {
+    return _g1mm->eden_space_used();
+  }
+  size_t max_size() const {
+    return _undefined_max;
+  }
+  MemoryUsage get_memory_usage();
+};
+
+// Memory pool that represents the G1 survivor.
+class G1SurvivorPool : public G1MemoryPoolSuper {
+public:
+  G1SurvivorPool(G1CollectedHeap* g1h);
+
+  size_t used_in_bytes() {
+    return _g1mm->survivor_space_used();
+  }
+  size_t max_size() const {
+    return _undefined_max;
+  }
+  MemoryUsage get_memory_usage();
+};
+
+// Memory pool that represents the G1 old gen.
+class G1OldGenPool : public G1MemoryPoolSuper {
+public:
+  G1OldGenPool(G1CollectedHeap* g1h);
+
+  size_t used_in_bytes() {
+    return _g1mm->old_space_used();
+  }
+  size_t max_size() const {
+    return _g1mm->old_gen_max();
+  }
+  MemoryUsage get_memory_usage();
+};
+
+#endif // SHARE_VM_GC_G1_G1MEMORYPOOL_HPP
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -33,6 +33,7 @@
 #include "gc/parallel/parallelScavengeHeap.inline.hpp"
 #include "gc/parallel/psAdaptiveSizePolicy.hpp"
 #include "gc/parallel/psMarkSweep.hpp"
+#include "gc/parallel/psMemoryPool.hpp"
 #include "gc/parallel/psParallelCompact.inline.hpp"
 #include "gc/parallel/psPromotionManager.hpp"
 #include "gc/parallel/psScavenge.hpp"
@@ -45,6 +46,7 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/vmThread.hpp"
+#include "services/memoryManager.hpp"
 #include "services/memTracker.hpp"
 #include "utilities/vmError.hpp"
 
@@ -119,7 +121,35 @@
   return JNI_OK;
 }
 
+void ParallelScavengeHeap::initialize_serviceability() {
+
+  _eden_pool = new EdenMutableSpacePool(_young_gen,
+                                        _young_gen->eden_space(),
+                                        "PS Eden Space",
+                                        false /* support_usage_threshold */);
+
+  _survivor_pool = new SurvivorMutableSpacePool(_young_gen,
+                                                "PS Survivor Space",
+                                                false /* support_usage_threshold */);
+
+  _old_pool = new PSGenerationPool(_old_gen,
+                                   "PS Old Gen",
+                                   true /* support_usage_threshold */);
+
+  _young_manager = new GCMemoryManager("PS Scavenge", "end of minor GC");
+  _old_manager = new GCMemoryManager("PS MarkSweep", "end of major GC");
+
+  _old_manager->add_pool(_eden_pool);
+  _old_manager->add_pool(_survivor_pool);
+  _old_manager->add_pool(_old_pool);
+
+  _young_manager->add_pool(_eden_pool);
+  _young_manager->add_pool(_survivor_pool);
+
+}
+
 void ParallelScavengeHeap::post_initialize() {
+  CollectedHeap::post_initialize();
   // Need to init the tenuring threshold
   PSScavenge::initialize();
   if (UseParallelOldGC) {
@@ -674,3 +704,19 @@
 void ParallelScavengeHeap::verify_nmethod(nmethod* nm) {
   CodeCache::verify_scavenge_root_nmethod(nm);
 }
+
+GrowableArray<GCMemoryManager*> ParallelScavengeHeap::memory_managers() {
+  GrowableArray<GCMemoryManager*> memory_managers(2);
+  memory_managers.append(_young_manager);
+  memory_managers.append(_old_manager);
+  return memory_managers;
+}
+
+GrowableArray<MemoryPool*> ParallelScavengeHeap::memory_pools() {
+  GrowableArray<MemoryPool*> memory_pools(3);
+  memory_pools.append(_eden_pool);
+  memory_pools.append(_survivor_pool);
+  memory_pools.append(_old_pool);
+  return memory_pools;
+}
+
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp	Thu Nov 30 13:40:07 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -36,11 +36,14 @@
 #include "gc/shared/gcWhen.hpp"
 #include "gc/shared/strongRootsScope.hpp"
 #include "memory/metaspace.hpp"
+#include "utilities/growableArray.hpp"
 #include "utilities/ostream.hpp"
 
 class AdjoiningGenerations;
 class GCHeapSummary;
 class GCTaskManager;
+class MemoryManager;
+class MemoryPool;
 class PSAdaptiveSizePolicy;
 class PSHeapSummary;
 
@@ -64,6 +67,15 @@
   // The task manager
   static GCTaskManager* _gc_task_manager;
 
+  GCMemoryManager* _young_manager;
+  GCMemoryManager* _old_manager;
+
+  MemoryPool* _eden_pool;
+  MemoryPool* _survivor_pool;
+  MemoryPool* _old_pool;
+
+  virtual void initialize_serviceability();
+
   void trace_heap(GCWhen::Type when, const GCTracer* tracer);
 
  protected:
@@ -94,6 +106,9 @@
 
   virtual CollectorPolicy* collector_policy() const { return _collector_policy; }
 
+  virtual GrowableArray<GCMemoryManager*> memory_managers();
+  virtual GrowableArray<MemoryPool*> memory_pools();
+
   static PSYoungGen* young_gen() { return _young_gen; }
   static PSOldGen* old_gen()     { return _old_gen; }
 
@@ -244,6 +259,9 @@
     ParStrongRootsScope();
     ~ParStrongRootsScope();
   };
+
+  GCMemoryManager* old_gc_manager() const { return _old_manager; }
+  GCMemoryManager* young_gc_manager() const { return _young_manager; }
 };
 
 // Simple class for storing info about the heap at the start of GC, to be used
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -172,7 +172,7 @@
     heap->pre_full_gc_dump(_gc_timer);
 
     TraceCollectorStats tcs(counters());
-    TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
+    TraceMemoryManagerStats tms(heap->old_gc_manager(),gc_cause);
 
     if (log_is_enabled(Debug, gc, heap, exit)) {
       accumulated_time()->start();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/parallel/psMemoryPool.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2007, 2017, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/parallel/psMemoryPool.hpp"
+
+PSGenerationPool::PSGenerationPool(PSOldGen* old_gen,
+                                   const char* name,
+                                   bool support_usage_threshold) :
+  CollectedMemoryPool(name, old_gen->capacity_in_bytes(),
+                      old_gen->reserved().byte_size(), support_usage_threshold), _old_gen(old_gen) {
+}
+
+MemoryUsage PSGenerationPool::get_memory_usage() {
+  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
+  size_t used      = used_in_bytes();
+  size_t committed = _old_gen->capacity_in_bytes();
+
+  return MemoryUsage(initial_size(), used, committed, maxSize);
+}
+
+// The max size of EdenMutableSpacePool =
+//     max size of the PSYoungGen - capacity of two survivor spaces
+//
+// Max size of PS eden space is changing due to ergonomic.
+// PSYoungGen, PSOldGen, Eden, Survivor spaces are all resizable.
+//
+EdenMutableSpacePool::EdenMutableSpacePool(PSYoungGen* young_gen,
+                                           MutableSpace* space,
+                                           const char* name,
+                                           bool support_usage_threshold) :
+  CollectedMemoryPool(name, space->capacity_in_bytes(),
+                      (young_gen->max_size() - young_gen->from_space()->capacity_in_bytes() - young_gen->to_space()->capacity_in_bytes()),
+                       support_usage_threshold),
+  _young_gen(young_gen),
+  _space(space) {
+}
+
+MemoryUsage EdenMutableSpacePool::get_memory_usage() {
+  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
+  size_t used = used_in_bytes();
+  size_t committed = _space->capacity_in_bytes();
+
+  return MemoryUsage(initial_size(), used, committed, maxSize);
+}
+
+// The max size of SurvivorMutableSpacePool =
+//     current capacity of the from-space
+//
+// PS from and to survivor spaces could have different sizes.
+//
+SurvivorMutableSpacePool::SurvivorMutableSpacePool(PSYoungGen* young_gen,
+                                                   const char* name,
+                                                   bool support_usage_threshold) :
+  CollectedMemoryPool(name, young_gen->from_space()->capacity_in_bytes(),
+                      young_gen->from_space()->capacity_in_bytes(),
+                      support_usage_threshold), _young_gen(young_gen) {
+}
+
+MemoryUsage SurvivorMutableSpacePool::get_memory_usage() {
+  size_t maxSize = (available_for_allocation() ? max_size() : 0);
+  size_t used    = used_in_bytes();
+  size_t committed = committed_in_bytes();
+  return MemoryUsage(initial_size(), used, committed, maxSize);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/parallel/psMemoryPool.hpp	Thu Nov 30 13:40:07 2017 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2007, 2017, 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_VM_SERVICES_PSMEMORYPOOL_HPP
+#define SHARE_VM_SERVICES_PSMEMORYPOOL_HPP
+
+#include "gc/parallel/mutableSpace.hpp"
+#include "gc/parallel/psOldGen.hpp"
+#include "gc/parallel/psYoungGen.hpp"
+#include "services/memoryPool.hpp"
+#include "services/memoryUsage.hpp"
+
+class PSGenerationPool : public CollectedMemoryPool {
+private:
+  PSOldGen* _old_gen;
+
+public:
+  PSGenerationPool(PSOldGen* pool, const char* name, bool support_usage_threshold);
+
+  MemoryUsage get_memory_usage();
+  size_t used_in_bytes() { return _old_gen->used_in_bytes(); }
+  size_t max_size() const { return _old_gen->reserved().byte_size(); }
+};
+
+class EdenMutableSpacePool : public CollectedMemoryPool {
+private:
+  PSYoungGen*   _young_gen;
+  MutableSpace* _space;
+
+public:
+  EdenMutableSpacePool(PSYoungGen* young_gen,
+                       MutableSpace* space,
+                       const char* name,
+                       bool support_usage_threshold);
+
+  MutableSpace* space()                     { return _space; }
+  MemoryUsage get_memory_usage();
+  size_t used_in_bytes()                    { return space()->used_in_bytes(); }
+  size_t max_size() const {
+    // Eden's max_size = max_size of Young Gen - the current committed size of survivor spaces
+    return _young_gen->max_size() - _young_gen->from_space()->capacity_in_bytes() - _young_gen->to_space()->capacity_in_bytes();
+  }
+};
+
+class SurvivorMutableSpacePool : public CollectedMemoryPool {
+private:
+  PSYoungGen*   _young_gen;
+
+public:
+  SurvivorMutableSpacePool(PSYoungGen* young_gen,
+                           const char* name,
+                           bool support_usage_threshold);
+
+  MemoryUsage get_memory_usage();
+
+  size_t used_in_bytes() {
+    return _young_gen->from_space()->used_in_bytes();
+  }
+  size_t committed_in_bytes() {
+    return _young_gen->from_space()->capacity_in_bytes();
+  }
+  size_t max_size() const {
+    // Return current committed size of the from-space
+    return _young_gen->from_space()->capacity_in_bytes();
+  }
+};
+
+#endif // SHARE_VM_SERVICES_PSMEMORYPOOL_HPP
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -1772,7 +1772,7 @@
     heap->pre_full_gc_dump(&_gc_timer);
 
     TraceCollectorStats tcs(counters());
-    TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
+    TraceMemoryManagerStats tms(heap->old_gc_manager(), gc_cause);
 
     if (log_is_enabled(Debug, gc, heap, exit)) {
       accumulated_time()->start();
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/parallel/psScavenge.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -305,7 +305,7 @@
     GCTraceCPUTime tcpu;
     GCTraceTime(Info, gc) tm("Pause Young", NULL, gc_cause, true);
     TraceCollectorStats tcs(counters());
-    TraceMemoryManagerStats tms(false /* not full GC */,gc_cause);
+    TraceMemoryManagerStats tms(heap->young_gc_manager(), gc_cause);
 
     if (log_is_enabled(Debug, gc, heap, exit)) {
       accumulated_time()->start();
--- a/src/hotspot/share/gc/serial/serialHeap.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/serial/serialHeap.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -23,9 +23,44 @@
  */
 
 #include "precompiled.hpp"
+#include "gc/serial/defNewGeneration.hpp"
 #include "gc/serial/serialHeap.hpp"
+#include "gc/shared/genMemoryPools.hpp"
+#include "services/memoryManager.hpp"
 
-SerialHeap::SerialHeap(GenCollectorPolicy* policy) : GenCollectedHeap(policy) {}
+SerialHeap::SerialHeap(GenCollectorPolicy* policy) :
+  GenCollectedHeap(policy), _eden_pool(NULL), _survivor_pool(NULL), _old_pool(NULL) {
+  _young_manager = new GCMemoryManager("Copy", "end of minor GC");
+  _old_manager = new GCMemoryManager("MarkSweepCompact", "end of major GC");
+}
+
+void SerialHeap::initialize_serviceability() {
+
+  DefNewGeneration* young = (DefNewGeneration*) young_gen();
+
+  // Add a memory pool for each space and young gen doesn't
+  // support low memory detection as it is expected to get filled up.
+  _eden_pool = new ContiguousSpacePool(young->eden(),
+                                       "Eden Space",
+                                       young->max_eden_size(),
+                                       false /* support_usage_threshold */);
+  _survivor_pool = new SurvivorContiguousSpacePool(young,
+                                                   "Survivor Space",
+                                                   young->max_survivor_size(),
+                                                   false /* support_usage_threshold */);
+  Generation* old = old_gen();
+  _old_pool = new GenerationPool(old, "Tenured Gen", true);
+
+  _young_manager->add_pool(_eden_pool);
+  _young_manager->add_pool(_survivor_pool);
+  young->set_gc_manager(_young_manager);
+
+  _old_manager->add_pool(_eden_pool);
+  _old_manager->add_pool(_survivor_pool);
+  _old_manager->add_pool(_old_pool);
+  old->set_gc_manager(_old_manager);
+
+}
 
 void SerialHeap::check_gen_kinds() {
   assert(young_gen()->kind() == Generation::DefNew,
@@ -33,3 +68,18 @@
   assert(old_gen()->kind() == Generation::MarkSweepCompact,
          "Wrong generation kind");
 }
+
+GrowableArray<GCMemoryManager*> SerialHeap::memory_managers() {
+  GrowableArray<GCMemoryManager*> memory_managers(2);
+  memory_managers.append(_young_manager);
+  memory_managers.append(_old_manager);
+  return memory_managers;
+}
+
+GrowableArray<MemoryPool*> SerialHeap::memory_pools() {
+  GrowableArray<MemoryPool*> memory_pools(3);
+  memory_pools.append(_eden_pool);
+  memory_pools.append(_survivor_pool);
+  memory_pools.append(_old_pool);
+  return memory_pools;
+}
--- a/src/hotspot/share/gc/serial/serialHeap.hpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/serial/serialHeap.hpp	Thu Nov 30 13:40:07 2017 +0100
@@ -26,10 +26,20 @@
 #define SHARE_VM_GC_SERIAL_SERIALHEAP_HPP
 
 #include "gc/shared/genCollectedHeap.hpp"
+#include "utilities/growableArray.hpp"
 
 class GenCollectorPolicy;
+class GCMemoryManager;
+class MemoryPool;
 
 class SerialHeap : public GenCollectedHeap {
+private:
+  MemoryPool* _eden_pool;
+  MemoryPool* _survivor_pool;
+  MemoryPool* _old_pool;
+
+  virtual void initialize_serviceability();
+
 protected:
   virtual void check_gen_kinds();
 
@@ -44,6 +54,9 @@
     return "Serial";
   }
 
+  virtual GrowableArray<GCMemoryManager*> memory_managers();
+  virtual GrowableArray<MemoryPool*> memory_pools();
+
   // override
   virtual bool is_in_closed_subset(const void* p) const {
     return is_in(p);
@@ -52,7 +65,6 @@
   virtual bool card_mark_must_follow_store() const {
     return false;
   }
-
 };
 
 #endif // SHARE_VM_GC_CMS_CMSHEAP_HPP
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -611,3 +611,7 @@
   _reserved.set_start(start);
   _reserved.set_end(end);
 }
+
+void CollectedHeap::post_initialize() {
+  initialize_serviceability();
+}
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp	Thu Nov 30 13:40:07 2017 +0100
@@ -34,6 +34,7 @@
 #include "utilities/debug.hpp"
 #include "utilities/events.hpp"
 #include "utilities/formatBuffer.hpp"
+#include "utilities/growableArray.hpp"
 
 // A "CollectedHeap" is an implementation of a java heap for HotSpot.  This
 // is an abstract class: there may be many different kinds of heaps.  This
@@ -46,6 +47,8 @@
 class GCHeapSummary;
 class GCTimer;
 class GCTracer;
+class GCMemoryManager;
+class MemoryPool;
 class MetaspaceSummary;
 class Thread;
 class ThreadClosure;
@@ -217,7 +220,7 @@
   // In many heaps, there will be a need to perform some initialization activities
   // after the Universe is fully formed, but before general heap allocation is allowed.
   // This is the correct place to place such initialization methods.
-  virtual void post_initialize() = 0;
+  virtual void post_initialize();
 
   // Stop any onging concurrent work and prepare for exit.
   virtual void stop() {}
@@ -485,6 +488,9 @@
   // Return the CollectorPolicy for the heap
   virtual CollectorPolicy* collector_policy() const = 0;
 
+  virtual GrowableArray<GCMemoryManager*> memory_managers() = 0;
+  virtual GrowableArray<MemoryPool*> memory_pools() = 0;
+
   // Iterate over all objects, calling "cl.do_object" on each.
   virtual void object_iterate(ObjectClosure* cl) = 0;
 
@@ -529,6 +535,9 @@
   // Generate any dumps preceding or following a full gc
  private:
   void full_gc_dump(GCTimer* timer, bool before);
+
+  virtual void initialize_serviceability() = 0;
+
  public:
   void pre_full_gc_dump(GCTimer* timer);
   void post_full_gc_dump(GCTimer* timer);
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -143,6 +143,7 @@
 }
 
 void GenCollectedHeap::post_initialize() {
+  CollectedHeap::post_initialize();
   ref_processing_init();
   check_gen_kinds();
   DefNewGeneration* def_new_gen = (DefNewGeneration*)_young_gen;
@@ -270,7 +271,7 @@
   FormatBuffer<> title("Collect gen: %s", gen->short_name());
   GCTraceTime(Trace, gc, phases) t1(title);
   TraceCollectorStats tcs(gen->counters());
-  TraceMemoryManagerStats tmms(gen->kind(),gc_cause());
+  TraceMemoryManagerStats tmms(gen->gc_manager(), gc_cause());
 
   gen->stat_record()->invocations++;
   gen->stat_record()->accumulated_time.start();
--- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp	Thu Nov 30 13:40:07 2017 +0100
@@ -112,6 +112,9 @@
   // (gen-specific) roots processing.
   SubTasksDone* _process_strong_tasks;
 
+  GCMemoryManager* _young_manager;
+  GCMemoryManager* _old_manager;
+
   // Helper functions for allocation
   HeapWord* attempt_allocation(size_t size,
                                bool   is_tlab,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/genMemoryPools.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/serial/defNewGeneration.hpp"
+#include "gc/shared/generation.hpp"
+#include "gc/shared/genMemoryPools.hpp"
+#include "gc/shared/space.hpp"
+
+ContiguousSpacePool::ContiguousSpacePool(ContiguousSpace* space,
+                                         const char* name,
+                                         size_t max_size,
+                                         bool support_usage_threshold) :
+  CollectedMemoryPool(name, space->capacity(), max_size,
+                      support_usage_threshold), _space(space) {
+}
+
+size_t ContiguousSpacePool::used_in_bytes() {
+  return space()->used();
+}
+
+MemoryUsage ContiguousSpacePool::get_memory_usage() {
+  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
+  size_t used      = used_in_bytes();
+  size_t committed = _space->capacity();
+
+  return MemoryUsage(initial_size(), used, committed, maxSize);
+}
+
+SurvivorContiguousSpacePool::SurvivorContiguousSpacePool(DefNewGeneration* young_gen,
+                                                         const char* name,
+                                                         size_t max_size,
+                                                         bool support_usage_threshold) :
+  CollectedMemoryPool(name, young_gen->from()->capacity(), max_size,
+                      support_usage_threshold), _young_gen(young_gen) {
+}
+
+size_t SurvivorContiguousSpacePool::used_in_bytes() {
+  return _young_gen->from()->used();
+}
+
+size_t SurvivorContiguousSpacePool::committed_in_bytes() {
+  return _young_gen->from()->capacity();
+}
+
+MemoryUsage SurvivorContiguousSpacePool::get_memory_usage() {
+  size_t maxSize = (available_for_allocation() ? max_size() : 0);
+  size_t used    = used_in_bytes();
+  size_t committed = committed_in_bytes();
+
+  return MemoryUsage(initial_size(), used, committed, maxSize);
+}
+
+GenerationPool::GenerationPool(Generation* gen,
+                               const char* name,
+                               bool support_usage_threshold) :
+  CollectedMemoryPool(name, gen->capacity(), gen->max_capacity(),
+                      support_usage_threshold), _gen(gen) {
+}
+
+size_t GenerationPool::used_in_bytes() {
+  return _gen->used();
+}
+
+MemoryUsage GenerationPool::get_memory_usage() {
+  size_t used      = used_in_bytes();
+  size_t committed = _gen->capacity();
+  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
+
+  return MemoryUsage(initial_size(), used, committed, maxSize);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/genMemoryPools.hpp	Thu Nov 30 13:40:07 2017 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, 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_VM_GC_SHARED_GENMEMORYPOOLS_HPP
+#define SHARE_VM_GC_SHARED_GENMEMORYPOOLS_HPP
+
+#include "services/memoryPool.hpp"
+
+class ContiguousSpace;
+class DefNewGeneration;
+class Generation;
+
+class ContiguousSpacePool : public CollectedMemoryPool {
+private:
+  ContiguousSpace* _space;
+
+public:
+  ContiguousSpacePool(ContiguousSpace* space,
+                      const char* name,
+                      size_t max_size,
+                      bool support_usage_threshold);
+
+  ContiguousSpace* space() { return _space; }
+  MemoryUsage get_memory_usage();
+  size_t used_in_bytes();
+};
+
+class SurvivorContiguousSpacePool : public CollectedMemoryPool {
+private:
+  DefNewGeneration* _young_gen;
+
+public:
+  SurvivorContiguousSpacePool(DefNewGeneration* young_gen,
+                              const char* name,
+                              size_t max_size,
+                              bool support_usage_threshold);
+
+  MemoryUsage get_memory_usage();
+
+  size_t used_in_bytes();
+  size_t committed_in_bytes();
+};
+
+class GenerationPool : public CollectedMemoryPool {
+private:
+  Generation* _gen;
+public:
+  GenerationPool(Generation* gen, const char* name, bool support_usage_threshold);
+
+  MemoryUsage get_memory_usage();
+  size_t used_in_bytes();
+};
+
+#endif // SHARE_VM_GC_SHARED_GENMEMORYPOOLS_HPP
--- a/src/hotspot/share/gc/shared/generation.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/shared/generation.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -44,7 +44,8 @@
 #include "utilities/events.hpp"
 
 Generation::Generation(ReservedSpace rs, size_t initial_size) :
-  _ref_processor(NULL) {
+  _ref_processor(NULL),
+  _gc_manager(NULL) {
   if (!_virtual_space.initialize(rs, initial_size)) {
     vm_exit_during_initialization("Could not reserve enough space for "
                     "object heap");
--- a/src/hotspot/share/gc/shared/generation.hpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/gc/shared/generation.hpp	Thu Nov 30 13:40:07 2017 +0100
@@ -58,6 +58,7 @@
 //
 
 class DefNewGeneration;
+class GCMemoryManager;
 class GenerationSpec;
 class CompactibleSpace;
 class ContiguousSpace;
@@ -86,6 +87,8 @@
   MemRegion _prev_used_region; // for collectors that want to "remember" a value for
                                // used region at some specific point during collection.
 
+  GCMemoryManager* _gc_manager;
+
  protected:
   // Minimum and maximum addresses for memory reserved (not necessarily
   // committed) for generation.
@@ -554,6 +557,16 @@
   // Performance Counter support
   virtual void update_counters() = 0;
   virtual CollectorCounters* counters() { return _gc_counters; }
+
+  GCMemoryManager* gc_manager() const {
+    assert(_gc_manager != NULL, "not initialized yet");
+    return _gc_manager;
+  }
+
+  void set_gc_manager(GCMemoryManager* gc_manager) {
+    _gc_manager = gc_manager;
+  }
+
 };
 
 #endif // SHARE_VM_GC_SHARED_GENERATION_HPP
--- a/src/hotspot/share/services/g1MemoryPool.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2007, 2015, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "gc/g1/g1CollectedHeap.hpp"
-#include "gc/g1/heapRegion.hpp"
-#include "services/g1MemoryPool.hpp"
-
-G1MemoryPoolSuper::G1MemoryPoolSuper(G1CollectedHeap* g1h,
-                                     const char* name,
-                                     size_t init_size,
-                                     size_t max_size,
-                                     bool support_usage_threshold) :
-  _g1mm(g1h->g1mm()), CollectedMemoryPool(name,
-                                          MemoryPool::Heap,
-                                          init_size,
-                                          max_size,
-                                          support_usage_threshold) {
-  assert(UseG1GC, "sanity");
-}
-
-G1EdenPool::G1EdenPool(G1CollectedHeap* g1h) :
-  G1MemoryPoolSuper(g1h,
-                    "G1 Eden Space",
-                    g1h->g1mm()->eden_space_committed(), /* init_size */
-                    _undefined_max,
-                    false /* support_usage_threshold */) { }
-
-MemoryUsage G1EdenPool::get_memory_usage() {
-  size_t initial_sz = initial_size();
-  size_t max_sz     = max_size();
-  size_t used       = used_in_bytes();
-  size_t committed  = _g1mm->eden_space_committed();
-
-  return MemoryUsage(initial_sz, used, committed, max_sz);
-}
-
-G1SurvivorPool::G1SurvivorPool(G1CollectedHeap* g1h) :
-  G1MemoryPoolSuper(g1h,
-                    "G1 Survivor Space",
-                    g1h->g1mm()->survivor_space_committed(), /* init_size */
-                    _undefined_max,
-                    false /* support_usage_threshold */) { }
-
-MemoryUsage G1SurvivorPool::get_memory_usage() {
-  size_t initial_sz = initial_size();
-  size_t max_sz     = max_size();
-  size_t used       = used_in_bytes();
-  size_t committed  = _g1mm->survivor_space_committed();
-
-  return MemoryUsage(initial_sz, used, committed, max_sz);
-}
-
-G1OldGenPool::G1OldGenPool(G1CollectedHeap* g1h) :
-  G1MemoryPoolSuper(g1h,
-                    "G1 Old Gen",
-                    g1h->g1mm()->old_space_committed(), /* init_size */
-                    g1h->g1mm()->old_gen_max(),
-                    true /* support_usage_threshold */) { }
-
-MemoryUsage G1OldGenPool::get_memory_usage() {
-  size_t initial_sz = initial_size();
-  size_t max_sz     = max_size();
-  size_t used       = used_in_bytes();
-  size_t committed  = _g1mm->old_space_committed();
-
-  return MemoryUsage(initial_sz, used, committed, max_sz);
-}
--- a/src/hotspot/share/services/g1MemoryPool.hpp	Thu Nov 30 08:35:33 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2007, 2015, 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_VM_SERVICES_G1MEMORYPOOL_HPP
-#define SHARE_VM_SERVICES_G1MEMORYPOOL_HPP
-
-#include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc/g1/g1MonitoringSupport.hpp"
-#include "services/memoryPool.hpp"
-#include "services/memoryUsage.hpp"
-#endif // INCLUDE_ALL_GCS
-
-// This file contains the three classes that represent the memory
-// pools of the G1 spaces: G1EdenPool, G1SurvivorPool, and
-// G1OldGenPool. In G1, unlike our other GCs, we do not have a
-// physical space for each of those spaces. Instead, we allocate
-// regions for all three spaces out of a single pool of regions (that
-// pool basically covers the entire heap). As a result, the eden,
-// survivor, and old gen are considered logical spaces in G1, as each
-// is a set of non-contiguous regions. This is also reflected in the
-// way we map them to memory pools here. The easiest way to have done
-// this would have been to map the entire G1 heap to a single memory
-// pool. However, it's helpful to show how large the eden and survivor
-// get, as this does affect the performance and behavior of G1. Which
-// is why we introduce the three memory pools implemented here.
-//
-// See comments in g1MonitoringSupport.hpp for additional details
-// on this model.
-//
-
-// This class is shared by the three G1 memory pool classes
-// (G1EdenPool, G1SurvivorPool, G1OldGenPool).
-class G1MemoryPoolSuper : public CollectedMemoryPool {
-protected:
-  const static size_t _undefined_max = (size_t) -1;
-  G1MonitoringSupport* _g1mm;
-
-  // Would only be called from subclasses.
-  G1MemoryPoolSuper(G1CollectedHeap* g1h,
-                    const char* name,
-                    size_t init_size,
-                    size_t max_size,
-                    bool support_usage_threshold);
-};
-
-// Memory pool that represents the G1 eden.
-class G1EdenPool : public G1MemoryPoolSuper {
-public:
-  G1EdenPool(G1CollectedHeap* g1h);
-
-  size_t used_in_bytes() {
-    return _g1mm->eden_space_used();
-  }
-  size_t max_size() const {
-    return _undefined_max;
-  }
-  MemoryUsage get_memory_usage();
-};
-
-// Memory pool that represents the G1 survivor.
-class G1SurvivorPool : public G1MemoryPoolSuper {
-public:
-  G1SurvivorPool(G1CollectedHeap* g1h);
-
-  size_t used_in_bytes() {
-    return _g1mm->survivor_space_used();
-  }
-  size_t max_size() const {
-    return _undefined_max;
-  }
-  MemoryUsage get_memory_usage();
-};
-
-// Memory pool that represents the G1 old gen.
-class G1OldGenPool : public G1MemoryPoolSuper {
-public:
-  G1OldGenPool(G1CollectedHeap* g1h);
-
-  size_t used_in_bytes() {
-    return _g1mm->old_space_used();
-  }
-  size_t max_size() const {
-    return _g1mm->old_gen_max();
-  }
-  MemoryUsage get_memory_usage();
-};
-
-#endif // SHARE_VM_SERVICES_G1MEMORYPOOL_HPP
--- a/src/hotspot/share/services/memoryManager.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/services/memoryManager.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -37,7 +37,7 @@
 #include "services/gcNotifier.hpp"
 #include "utilities/dtrace.hpp"
 
-MemoryManager::MemoryManager() {
+MemoryManager::MemoryManager(const char* name) : _name(name) {
   _num_pools = 0;
   (void)const_cast<instanceOop&>(_memory_mgr_obj = instanceOop(NULL));
 }
@@ -52,43 +52,11 @@
 }
 
 MemoryManager* MemoryManager::get_code_cache_memory_manager() {
-  return (MemoryManager*) new CodeCacheMemoryManager();
+  return new MemoryManager("CodeCacheManager");
 }
 
 MemoryManager* MemoryManager::get_metaspace_memory_manager() {
-  return (MemoryManager*) new MetaspaceMemoryManager();
-}
-
-GCMemoryManager* MemoryManager::get_copy_memory_manager() {
-  return (GCMemoryManager*) new CopyMemoryManager();
-}
-
-GCMemoryManager* MemoryManager::get_msc_memory_manager() {
-  return (GCMemoryManager*) new MSCMemoryManager();
-}
-
-GCMemoryManager* MemoryManager::get_parnew_memory_manager() {
-  return (GCMemoryManager*) new ParNewMemoryManager();
-}
-
-GCMemoryManager* MemoryManager::get_cms_memory_manager() {
-  return (GCMemoryManager*) new CMSMemoryManager();
-}
-
-GCMemoryManager* MemoryManager::get_psScavenge_memory_manager() {
-  return (GCMemoryManager*) new PSScavengeMemoryManager();
-}
-
-GCMemoryManager* MemoryManager::get_psMarkSweep_memory_manager() {
-  return (GCMemoryManager*) new PSMarkSweepMemoryManager();
-}
-
-GCMemoryManager* MemoryManager::get_g1YoungGen_memory_manager() {
-  return (GCMemoryManager*) new G1YoungGenMemoryManager();
-}
-
-GCMemoryManager* MemoryManager::get_g1OldGen_memory_manager() {
-  return (GCMemoryManager*) new G1OldGenMemoryManager();
+  return new MemoryManager("Metaspace Manager");
 }
 
 instanceOop MemoryManager::get_memory_manager_instance(TRAPS) {
@@ -203,7 +171,8 @@
 }
 
 
-GCMemoryManager::GCMemoryManager() : MemoryManager() {
+GCMemoryManager::GCMemoryManager(const char* name, const char* gc_end_message) :
+  MemoryManager(name), _gc_end_message(gc_end_message) {
   _num_collections = 0;
   _last_gc_stat = NULL;
   _last_gc_lock = new Mutex(Mutex::leaf, "_last_gc_lock", true,
@@ -308,9 +277,7 @@
     }
 
     if (is_notification_enabled()) {
-      bool isMajorGC = this == MemoryService::get_major_gc_manager();
-      GCNotifier::pushNotification(this, isMajorGC ? "end of major GC" : "end of minor GC",
-                                   GCCause::to_string(cause));
+      GCNotifier::pushNotification(this, _gc_end_message, GCCause::to_string(cause));
     }
   }
 }
--- a/src/hotspot/share/services/memoryManager.hpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/services/memoryManager.hpp	Thu Nov 30 13:40:07 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -52,11 +52,13 @@
   MemoryPool* _pools[max_num_pools];
   int         _num_pools;
 
+  const char* _name;
+
 protected:
   volatile instanceOop _memory_mgr_obj;
 
 public:
-  MemoryManager();
+  MemoryManager(const char* name);
 
   int num_memory_pools() const           { return _num_pools; }
   MemoryPool* get_memory_pool(int index) {
@@ -70,7 +72,8 @@
 
   virtual instanceOop get_memory_manager_instance(TRAPS);
   virtual bool is_gc_memory_manager()    { return false; }
-  virtual const char* name() = 0;
+
+  const char* name() const { return _name; }
 
   // GC support
   void oops_do(OopClosure* f);
@@ -78,29 +81,6 @@
   // Static factory methods to get a memory manager of a specific type
   static MemoryManager*   get_code_cache_memory_manager();
   static MemoryManager*   get_metaspace_memory_manager();
-  static GCMemoryManager* get_copy_memory_manager();
-  static GCMemoryManager* get_msc_memory_manager();
-  static GCMemoryManager* get_parnew_memory_manager();
-  static GCMemoryManager* get_cms_memory_manager();
-  static GCMemoryManager* get_psScavenge_memory_manager();
-  static GCMemoryManager* get_psMarkSweep_memory_manager();
-  static GCMemoryManager* get_g1YoungGen_memory_manager();
-  static GCMemoryManager* get_g1OldGen_memory_manager();
-};
-
-class CodeCacheMemoryManager : public MemoryManager {
-private:
-public:
-  CodeCacheMemoryManager() : MemoryManager() {}
-
-  const char* name() { return "CodeCacheManager"; }
-};
-
-class MetaspaceMemoryManager : public MemoryManager {
-public:
-  MetaspaceMemoryManager() : MemoryManager() {}
-
-  const char* name() { return "Metaspace Manager"; }
 };
 
 class GCStatInfo : public ResourceObj {
@@ -162,8 +142,9 @@
   GCStatInfo*  _current_gc_stat;
   int          _num_gc_threads;
   volatile bool _notification_enabled;
+  const char* _gc_end_message;
 public:
-  GCMemoryManager();
+  GCMemoryManager(const char* name, const char* gc_end_message);
   ~GCMemoryManager();
 
   void   initialize_gc_stat_info();
@@ -189,71 +170,4 @@
   bool is_notification_enabled() { return _notification_enabled; }
 };
 
-// These subclasses of GCMemoryManager are defined to include
-// GC-specific information.
-// TODO: Add GC-specific information
-class CopyMemoryManager : public GCMemoryManager {
-private:
-public:
-  CopyMemoryManager() : GCMemoryManager() {}
-
-  const char* name() { return "Copy"; }
-};
-
-class MSCMemoryManager : public GCMemoryManager {
-private:
-public:
-  MSCMemoryManager() : GCMemoryManager() {}
-
-  const char* name() { return "MarkSweepCompact"; }
-};
-
-class ParNewMemoryManager : public GCMemoryManager {
-private:
-public:
-  ParNewMemoryManager() : GCMemoryManager() {}
-
-  const char* name() { return "ParNew"; }
-};
-
-class CMSMemoryManager : public GCMemoryManager {
-private:
-public:
-  CMSMemoryManager() : GCMemoryManager() {}
-
-  const char* name() { return "ConcurrentMarkSweep";}
-};
-
-class PSScavengeMemoryManager : public GCMemoryManager {
-private:
-public:
-  PSScavengeMemoryManager() : GCMemoryManager() {}
-
-  const char* name() { return "PS Scavenge"; }
-};
-
-class PSMarkSweepMemoryManager : public GCMemoryManager {
-private:
-public:
-  PSMarkSweepMemoryManager() : GCMemoryManager() {}
-
-  const char* name() { return "PS MarkSweep"; }
-};
-
-class G1YoungGenMemoryManager : public GCMemoryManager {
-private:
-public:
-  G1YoungGenMemoryManager() : GCMemoryManager() {}
-
-  const char* name() { return "G1 Young Generation"; }
-};
-
-class G1OldGenMemoryManager : public GCMemoryManager {
-private:
-public:
-  G1OldGenMemoryManager() : GCMemoryManager() {}
-
-  const char* name() { return "G1 Old Generation"; }
-};
-
 #endif // SHARE_VM_SERVICES_MEMORYMANAGER_HPP
--- a/src/hotspot/share/services/memoryPool.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/services/memoryPool.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -25,8 +25,6 @@
 #include "precompiled.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
-#include "gc/serial/defNewGeneration.hpp"
-#include "gc/shared/space.hpp"
 #include "memory/metaspace.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/handles.inline.hpp"
@@ -38,9 +36,6 @@
 #include "services/memoryPool.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc/cms/compactibleFreeListSpace.hpp"
-#endif
 
 MemoryPool::MemoryPool(const char* name,
                        PoolType type,
@@ -182,95 +177,6 @@
   }
 }
 
-ContiguousSpacePool::ContiguousSpacePool(ContiguousSpace* space,
-                                         const char* name,
-                                         PoolType type,
-                                         size_t max_size,
-                                         bool support_usage_threshold) :
-  CollectedMemoryPool(name, type, space->capacity(), max_size,
-                      support_usage_threshold), _space(space) {
-}
-
-size_t ContiguousSpacePool::used_in_bytes() {
-  return space()->used();
-}
-
-MemoryUsage ContiguousSpacePool::get_memory_usage() {
-  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
-  size_t used      = used_in_bytes();
-  size_t committed = _space->capacity();
-
-  return MemoryUsage(initial_size(), used, committed, maxSize);
-}
-
-SurvivorContiguousSpacePool::SurvivorContiguousSpacePool(DefNewGeneration* young_gen,
-                                                         const char* name,
-                                                         PoolType type,
-                                                         size_t max_size,
-                                                         bool support_usage_threshold) :
-  CollectedMemoryPool(name, type, young_gen->from()->capacity(), max_size,
-                      support_usage_threshold), _young_gen(young_gen) {
-}
-
-size_t SurvivorContiguousSpacePool::used_in_bytes() {
-  return _young_gen->from()->used();
-}
-
-size_t SurvivorContiguousSpacePool::committed_in_bytes() {
-  return _young_gen->from()->capacity();
-}
-
-MemoryUsage SurvivorContiguousSpacePool::get_memory_usage() {
-  size_t maxSize = (available_for_allocation() ? max_size() : 0);
-  size_t used    = used_in_bytes();
-  size_t committed = committed_in_bytes();
-
-  return MemoryUsage(initial_size(), used, committed, maxSize);
-}
-
-#if INCLUDE_ALL_GCS
-CompactibleFreeListSpacePool::CompactibleFreeListSpacePool(CompactibleFreeListSpace* space,
-                                                           const char* name,
-                                                           PoolType type,
-                                                           size_t max_size,
-                                                           bool support_usage_threshold) :
-  CollectedMemoryPool(name, type, space->capacity(), max_size,
-                      support_usage_threshold), _space(space) {
-}
-
-size_t CompactibleFreeListSpacePool::used_in_bytes() {
-  return _space->used();
-}
-
-MemoryUsage CompactibleFreeListSpacePool::get_memory_usage() {
-  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
-  size_t used      = used_in_bytes();
-  size_t committed = _space->capacity();
-
-  return MemoryUsage(initial_size(), used, committed, maxSize);
-}
-#endif // INCLUDE_ALL_GCS
-
-GenerationPool::GenerationPool(Generation* gen,
-                               const char* name,
-                               PoolType type,
-                               bool support_usage_threshold) :
-  CollectedMemoryPool(name, type, gen->capacity(), gen->max_capacity(),
-                      support_usage_threshold), _gen(gen) {
-}
-
-size_t GenerationPool::used_in_bytes() {
-  return _gen->used();
-}
-
-MemoryUsage GenerationPool::get_memory_usage() {
-  size_t used      = used_in_bytes();
-  size_t committed = _gen->capacity();
-  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
-
-  return MemoryUsage(initial_size(), used, committed, maxSize);
-}
-
 CodeHeapPool::CodeHeapPool(CodeHeap* codeHeap, const char* name, bool support_usage_threshold) :
   MemoryPool(name, NonHeap, codeHeap->capacity(), codeHeap->max_capacity(),
              support_usage_threshold, false), _codeHeap(codeHeap) {
--- a/src/hotspot/share/services/memoryPool.hpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/services/memoryPool.hpp	Thu Nov 30 13:40:07 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -37,12 +37,8 @@
 // both heap and non-heap memory.
 
 // Forward declaration
-class CompactibleFreeListSpace;
-class ContiguousSpace;
 class MemoryManager;
 class SensorInfo;
-class Generation;
-class DefNewGeneration;
 class ThresholdSupport;
 
 class MemoryPool : public CHeapObj<mtInternal> {
@@ -144,67 +140,11 @@
 
 class CollectedMemoryPool : public MemoryPool {
 public:
-  CollectedMemoryPool(const char* name, PoolType type, size_t init_size, size_t max_size, bool support_usage_threshold) :
-    MemoryPool(name, type, init_size, max_size, support_usage_threshold, true) {};
+  CollectedMemoryPool(const char* name, size_t init_size, size_t max_size, bool support_usage_threshold) :
+    MemoryPool(name, MemoryPool::Heap, init_size, max_size, support_usage_threshold, true) {};
   bool is_collected_pool()            { return true; }
 };
 
-class ContiguousSpacePool : public CollectedMemoryPool {
-private:
-  ContiguousSpace* _space;
-
-public:
-  ContiguousSpacePool(ContiguousSpace* space, const char* name, PoolType type, size_t max_size, bool support_usage_threshold);
-
-  ContiguousSpace* space()              { return _space; }
-  MemoryUsage get_memory_usage();
-  size_t used_in_bytes();
-};
-
-class SurvivorContiguousSpacePool : public CollectedMemoryPool {
-private:
-  DefNewGeneration* _young_gen;
-
-public:
-  SurvivorContiguousSpacePool(DefNewGeneration* young_gen,
-                              const char* name,
-                              PoolType type,
-                              size_t max_size,
-                              bool support_usage_threshold);
-
-  MemoryUsage get_memory_usage();
-
-  size_t used_in_bytes();
-  size_t committed_in_bytes();
-};
-
-#if INCLUDE_ALL_GCS
-class CompactibleFreeListSpacePool : public CollectedMemoryPool {
-private:
-  CompactibleFreeListSpace* _space;
-public:
-  CompactibleFreeListSpacePool(CompactibleFreeListSpace* space,
-                               const char* name,
-                               PoolType type,
-                               size_t max_size,
-                               bool support_usage_threshold);
-
-  MemoryUsage get_memory_usage();
-  size_t used_in_bytes();
-};
-#endif // INCLUDE_ALL_GCS
-
-
-class GenerationPool : public CollectedMemoryPool {
-private:
-  Generation* _gen;
-public:
-  GenerationPool(Generation* gen, const char* name, PoolType type, bool support_usage_threshold);
-
-  MemoryUsage get_memory_usage();
-  size_t used_in_bytes();
-};
-
 class CodeHeapPool: public MemoryPool {
 private:
   CodeHeap* _codeHeap;
--- a/src/hotspot/share/services/memoryService.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/services/memoryService.cpp	Thu Nov 30 13:40:07 2017 +0100
@@ -25,13 +25,7 @@
 #include "precompiled.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
-#include "gc/parallel/mutableSpace.hpp"
-#include "gc/serial/defNewGeneration.hpp"
-#include "gc/serial/tenuredGeneration.hpp"
-#include "gc/shared/collectorPolicy.hpp"
-#include "gc/shared/genCollectedHeap.hpp"
-#include "gc/shared/generation.hpp"
-#include "gc/shared/generationSpec.hpp"
+#include "gc/shared/collectedHeap.hpp"
 #include "logging/logConfiguration.hpp"
 #include "memory/heap.hpp"
 #include "memory/memRegion.hpp"
@@ -46,24 +40,12 @@
 #include "services/memoryService.hpp"
 #include "utilities/growableArray.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc/cms/concurrentMarkSweepGeneration.hpp"
-#include "gc/cms/parNewGeneration.hpp"
-#include "gc/g1/g1CollectedHeap.inline.hpp"
-#include "gc/parallel/parallelScavengeHeap.hpp"
-#include "gc/parallel/psOldGen.hpp"
-#include "gc/parallel/psYoungGen.hpp"
-#include "services/g1MemoryPool.hpp"
-#include "services/psMemoryPool.hpp"
-#endif // INCLUDE_ALL_GCS
 
 GrowableArray<MemoryPool*>* MemoryService::_pools_list =
   new (ResourceObj::C_HEAP, mtInternal) GrowableArray<MemoryPool*>(init_pools_list_size, true);
 GrowableArray<MemoryManager*>* MemoryService::_managers_list =
   new (ResourceObj::C_HEAP, mtInternal) GrowableArray<MemoryManager*>(init_managers_list_size, true);
 
-GCMemoryManager* MemoryService::_minor_gc_manager      = NULL;
-GCMemoryManager* MemoryService::_major_gc_manager      = NULL;
 MemoryManager*   MemoryService::_code_cache_manager    = NULL;
 GrowableArray<MemoryPool*>* MemoryService::_code_heap_pools =
     new (ResourceObj::C_HEAP, mtInternal) GrowableArray<MemoryPool*>(init_code_heap_pools_size, true);
@@ -84,311 +66,28 @@
 }
 
 void MemoryService::set_universe_heap(CollectedHeap* heap) {
-  CollectedHeap::Name kind = heap->kind();
-  switch (kind) {
-    case CollectedHeap::SerialHeap :
-    case CollectedHeap::CMSHeap : {
-      add_gen_collected_heap_info(GenCollectedHeap::heap());
-      break;
-    }
-#if INCLUDE_ALL_GCS
-    case CollectedHeap::ParallelScavengeHeap : {
-      add_parallel_scavenge_heap_info(ParallelScavengeHeap::heap());
-      break;
-    }
-    case CollectedHeap::G1CollectedHeap : {
-      add_g1_heap_info(G1CollectedHeap::heap());
-      break;
-    }
-#endif // INCLUDE_ALL_GCS
-    default: {
-      guarantee(false, "Unrecognized kind of heap");
-    }
-  }
+  ResourceMark rm; // For internal allocations in GrowableArray.
+
+  GrowableArray<MemoryPool*> gc_mem_pools = heap->memory_pools();
+  _pools_list->appendAll(&gc_mem_pools);
 
   // set the GC thread count
   GcThreadCountClosure gctcc;
   heap->gc_threads_do(&gctcc);
   int count = gctcc.count();
-  if (count > 0) {
-    _minor_gc_manager->set_num_gc_threads(count);
-    _major_gc_manager->set_num_gc_threads(count);
-  }
 
-  // All memory pools and memory managers are initialized.
-  //
-  _minor_gc_manager->initialize_gc_stat_info();
-  _major_gc_manager->initialize_gc_stat_info();
-}
+  GrowableArray<GCMemoryManager*> gc_memory_managers = heap->memory_managers();
+  for (int i = 0; i < gc_memory_managers.length(); i++) {
+    GCMemoryManager* gc_manager = gc_memory_managers.at(i);
 
-// Add memory pools for GenCollectedHeap
-// This function currently only supports two generations collected heap.
-// The collector for GenCollectedHeap will have two memory managers.
-void MemoryService::add_gen_collected_heap_info(GenCollectedHeap* heap) {
-  CollectorPolicy* policy = heap->collector_policy();
-
-  assert(policy->is_generation_policy(), "Only support two generations");
-  GenCollectorPolicy* gen_policy = policy->as_generation_policy();
-  if (gen_policy != NULL) {
-    Generation::Name kind = gen_policy->young_gen_spec()->name();
-    switch (kind) {
-      case Generation::DefNew:
-        _minor_gc_manager = MemoryManager::get_copy_memory_manager();
-        break;
-#if INCLUDE_ALL_GCS
-      case Generation::ParNew:
-        _minor_gc_manager = MemoryManager::get_parnew_memory_manager();
-        break;
-#endif // INCLUDE_ALL_GCS
-      default:
-        guarantee(false, "Unrecognized generation spec");
-        break;
+    if (count > 0) {
+      gc_manager->set_num_gc_threads(count);
     }
-    if (policy->is_mark_sweep_policy()) {
-      _major_gc_manager = MemoryManager::get_msc_memory_manager();
-#if INCLUDE_ALL_GCS
-    } else if (policy->is_concurrent_mark_sweep_policy()) {
-      _major_gc_manager = MemoryManager::get_cms_memory_manager();
-#endif // INCLUDE_ALL_GCS
-    } else {
-      guarantee(false, "Unknown two-gen policy");
-    }
-  } else {
-    guarantee(false, "Non two-gen policy");
-  }
-  _managers_list->append(_minor_gc_manager);
-  _managers_list->append(_major_gc_manager);
-
-  add_generation_memory_pool(heap->young_gen(), _major_gc_manager, _minor_gc_manager);
-  add_generation_memory_pool(heap->old_gen(), _major_gc_manager);
-}
-
-#if INCLUDE_ALL_GCS
-// Add memory pools for ParallelScavengeHeap
-// This function currently only supports two generations collected heap.
-// The collector for ParallelScavengeHeap will have two memory managers.
-void MemoryService::add_parallel_scavenge_heap_info(ParallelScavengeHeap* heap) {
-  // Two managers to keep statistics about _minor_gc_manager and _major_gc_manager GC.
-  _minor_gc_manager = MemoryManager::get_psScavenge_memory_manager();
-  _major_gc_manager = MemoryManager::get_psMarkSweep_memory_manager();
-  _managers_list->append(_minor_gc_manager);
-  _managers_list->append(_major_gc_manager);
-
-  add_psYoung_memory_pool(heap->young_gen(), _major_gc_manager, _minor_gc_manager);
-  add_psOld_memory_pool(heap->old_gen(), _major_gc_manager);
-}
-
-void MemoryService::add_g1_heap_info(G1CollectedHeap* g1h) {
-  assert(UseG1GC, "sanity");
-
-  _minor_gc_manager = MemoryManager::get_g1YoungGen_memory_manager();
-  _major_gc_manager = MemoryManager::get_g1OldGen_memory_manager();
-  _managers_list->append(_minor_gc_manager);
-  _managers_list->append(_major_gc_manager);
-
-  add_g1YoungGen_memory_pool(g1h, _major_gc_manager, _minor_gc_manager);
-  add_g1OldGen_memory_pool(g1h, _major_gc_manager);
-}
-#endif // INCLUDE_ALL_GCS
-
-MemoryPool* MemoryService::add_gen(Generation* gen,
-                                   const char* name,
-                                   bool is_heap,
-                                   bool support_usage_threshold) {
-
-  MemoryPool::PoolType type = (is_heap ? MemoryPool::Heap : MemoryPool::NonHeap);
-  GenerationPool* pool = new GenerationPool(gen, name, type, support_usage_threshold);
-  _pools_list->append(pool);
-  return (MemoryPool*) pool;
-}
-
-MemoryPool* MemoryService::add_space(ContiguousSpace* space,
-                                     const char* name,
-                                     bool is_heap,
-                                     size_t max_size,
-                                     bool support_usage_threshold) {
-  MemoryPool::PoolType type = (is_heap ? MemoryPool::Heap : MemoryPool::NonHeap);
-  ContiguousSpacePool* pool = new ContiguousSpacePool(space, name, type, max_size, support_usage_threshold);
-
-  _pools_list->append(pool);
-  return (MemoryPool*) pool;
-}
-
-MemoryPool* MemoryService::add_survivor_spaces(DefNewGeneration* young_gen,
-                                               const char* name,
-                                               bool is_heap,
-                                               size_t max_size,
-                                               bool support_usage_threshold) {
-  MemoryPool::PoolType type = (is_heap ? MemoryPool::Heap : MemoryPool::NonHeap);
-  SurvivorContiguousSpacePool* pool = new SurvivorContiguousSpacePool(young_gen, name, type, max_size, support_usage_threshold);
-
-  _pools_list->append(pool);
-  return (MemoryPool*) pool;
-}
-
-#if INCLUDE_ALL_GCS
-MemoryPool* MemoryService::add_cms_space(CompactibleFreeListSpace* space,
-                                         const char* name,
-                                         bool is_heap,
-                                         size_t max_size,
-                                         bool support_usage_threshold) {
-  MemoryPool::PoolType type = (is_heap ? MemoryPool::Heap : MemoryPool::NonHeap);
-  CompactibleFreeListSpacePool* pool = new CompactibleFreeListSpacePool(space, name, type, max_size, support_usage_threshold);
-  _pools_list->append(pool);
-  return (MemoryPool*) pool;
-}
-#endif // INCLUDE_ALL_GCS
-
-// Add memory pool(s) for one generation
-void MemoryService::add_generation_memory_pool(Generation* gen,
-                                               MemoryManager* major_mgr,
-                                               MemoryManager* minor_mgr) {
-  guarantee(gen != NULL, "No generation for memory pool");
-  Generation::Name kind = gen->kind();
-  int index = _pools_list->length();
-
-  switch (kind) {
-    case Generation::DefNew: {
-      assert(major_mgr != NULL && minor_mgr != NULL, "Should have two managers");
-      DefNewGeneration* young_gen = (DefNewGeneration*) gen;
-      // Add a memory pool for each space and young gen doesn't
-      // support low memory detection as it is expected to get filled up.
-      MemoryPool* eden = add_space(young_gen->eden(),
-                                   "Eden Space",
-                                   true, /* is_heap */
-                                   young_gen->max_eden_size(),
-                                   false /* support_usage_threshold */);
-      MemoryPool* survivor = add_survivor_spaces(young_gen,
-                                                 "Survivor Space",
-                                                 true, /* is_heap */
-                                                 young_gen->max_survivor_size(),
-                                                 false /* support_usage_threshold */);
-      break;
-    }
-
-#if INCLUDE_ALL_GCS
-    case Generation::ParNew:
-    {
-      assert(major_mgr != NULL && minor_mgr != NULL, "Should have two managers");
-      // Add a memory pool for each space and young gen doesn't
-      // support low memory detection as it is expected to get filled up.
-      ParNewGeneration* parnew_gen = (ParNewGeneration*) gen;
-      MemoryPool* eden = add_space(parnew_gen->eden(),
-                                   "Par Eden Space",
-                                   true /* is_heap */,
-                                   parnew_gen->max_eden_size(),
-                                   false /* support_usage_threshold */);
-      MemoryPool* survivor = add_survivor_spaces(parnew_gen,
-                                                 "Par Survivor Space",
-                                                 true, /* is_heap */
-                                                 parnew_gen->max_survivor_size(),
-                                                 false /* support_usage_threshold */);
-
-      break;
-    }
-#endif // INCLUDE_ALL_GCS
-
-    case Generation::MarkSweepCompact: {
-      assert(major_mgr != NULL && minor_mgr == NULL, "Should have only one manager");
-      add_gen(gen,
-              "Tenured Gen",
-              true, /* is_heap */
-              true  /* support_usage_threshold */);
-      break;
-    }
-
-#if INCLUDE_ALL_GCS
-    case Generation::ConcurrentMarkSweep:
-    {
-      assert(major_mgr != NULL && minor_mgr == NULL, "Should have only one manager");
-      ConcurrentMarkSweepGeneration* cms = (ConcurrentMarkSweepGeneration*) gen;
-      MemoryPool* pool = add_cms_space(cms->cmsSpace(),
-                                       "CMS Old Gen",
-                                       true, /* is_heap */
-                                       cms->reserved().byte_size(),
-                                       true  /* support_usage_threshold */);
-      break;
-    }
-#endif // INCLUDE_ALL_GCS
-
-    default:
-      assert(false, "should not reach here");
-      // no memory pool added for others
-      break;
-  }
-
-  assert(major_mgr != NULL, "Should have at least one manager");
-  // Link managers and the memory pools together
-  for (int i = index; i < _pools_list->length(); i++) {
-    MemoryPool* pool = _pools_list->at(i);
-    major_mgr->add_pool(pool);
-    if (minor_mgr != NULL) {
-      minor_mgr->add_pool(pool);
-    }
+    gc_manager->initialize_gc_stat_info();
+    _managers_list->append(gc_manager);
   }
 }
 
-
-#if INCLUDE_ALL_GCS
-void MemoryService::add_psYoung_memory_pool(PSYoungGen* young_gen, MemoryManager* major_mgr, MemoryManager* minor_mgr) {
-  assert(major_mgr != NULL && minor_mgr != NULL, "Should have two managers");
-
-  // Add a memory pool for each space and young gen doesn't
-  // support low memory detection as it is expected to get filled up.
-  EdenMutableSpacePool* eden = new EdenMutableSpacePool(young_gen,
-                                                        young_gen->eden_space(),
-                                                        "PS Eden Space",
-                                                        MemoryPool::Heap,
-                                                        false /* support_usage_threshold */);
-
-  SurvivorMutableSpacePool* survivor = new SurvivorMutableSpacePool(young_gen,
-                                                                    "PS Survivor Space",
-                                                                    MemoryPool::Heap,
-                                                                    false /* support_usage_threshold */);
-
-  major_mgr->add_pool(eden);
-  major_mgr->add_pool(survivor);
-  minor_mgr->add_pool(eden);
-  minor_mgr->add_pool(survivor);
-  _pools_list->append(eden);
-  _pools_list->append(survivor);
-}
-
-void MemoryService::add_psOld_memory_pool(PSOldGen* old_gen, MemoryManager* mgr) {
-  PSGenerationPool* old_gen_pool = new PSGenerationPool(old_gen,
-                                                       "PS Old Gen",
-                                                       MemoryPool::Heap,
-                                                       true /* support_usage_threshold */);
-  mgr->add_pool(old_gen_pool);
-  _pools_list->append(old_gen_pool);
-}
-
-void MemoryService::add_g1YoungGen_memory_pool(G1CollectedHeap* g1h,
-                                               MemoryManager* major_mgr,
-                                               MemoryManager* minor_mgr) {
-  assert(major_mgr != NULL && minor_mgr != NULL, "should have two managers");
-
-  G1EdenPool* eden = new G1EdenPool(g1h);
-  G1SurvivorPool* survivor = new G1SurvivorPool(g1h);
-
-  major_mgr->add_pool(eden);
-  major_mgr->add_pool(survivor);
-  minor_mgr->add_pool(eden);
-  minor_mgr->add_pool(survivor);
-  _pools_list->append(eden);
-  _pools_list->append(survivor);
-}
-
-void MemoryService::add_g1OldGen_memory_pool(G1CollectedHeap* g1h,
-                                             MemoryManager* mgr) {
-  assert(mgr != NULL, "should have one manager");
-
-  G1OldGenPool* old_gen = new G1OldGenPool(g1h);
-  mgr->add_pool(old_gen);
-  _pools_list->append(old_gen);
-}
-#endif // INCLUDE_ALL_GCS
-
 void MemoryService::add_code_heap_memory_pool(CodeHeap* heap, const char* name) {
   // Create new memory pool for this heap
   MemoryPool* code_heap_pool = new CodeHeapPool(heap, name, true /* support_usage_threshold */);
@@ -463,18 +162,11 @@
   }
 }
 
-void MemoryService::gc_begin(bool fullGC, bool recordGCBeginTime,
+void MemoryService::gc_begin(GCMemoryManager* manager, bool recordGCBeginTime,
                              bool recordAccumulatedGCTime,
                              bool recordPreGCUsage, bool recordPeakUsage) {
 
-  GCMemoryManager* mgr;
-  if (fullGC) {
-    mgr = _major_gc_manager;
-  } else {
-    mgr = _minor_gc_manager;
-  }
-  assert(mgr->is_gc_memory_manager(), "Sanity check");
-  mgr->gc_begin(recordGCBeginTime, recordPreGCUsage, recordAccumulatedGCTime);
+  manager->gc_begin(recordGCBeginTime, recordPreGCUsage, recordAccumulatedGCTime);
 
   // Track the peak memory usage when GC begins
   if (recordPeakUsage) {
@@ -485,22 +177,13 @@
   }
 }
 
-void MemoryService::gc_end(bool fullGC, bool recordPostGCUsage,
+void MemoryService::gc_end(GCMemoryManager* manager, bool recordPostGCUsage,
                            bool recordAccumulatedGCTime,
                            bool recordGCEndTime, bool countCollection,
                            GCCause::Cause cause) {
-
-  GCMemoryManager* mgr;
-  if (fullGC) {
-    mgr = (GCMemoryManager*) _major_gc_manager;
-  } else {
-    mgr = (GCMemoryManager*) _minor_gc_manager;
-  }
-  assert(mgr->is_gc_memory_manager(), "Sanity check");
-
   // register the GC end statistics and memory usage
-  mgr->gc_end(recordPostGCUsage, recordAccumulatedGCTime, recordGCEndTime,
-              countCollection, cause);
+  manager->gc_end(recordPostGCUsage, recordAccumulatedGCTime, recordGCEndTime,
+                  countCollection, cause);
 }
 
 void MemoryService::oops_do(OopClosure* f) {
@@ -551,36 +234,7 @@
   return obj;
 }
 
-// GC manager type depends on the type of Generation. Depending on the space
-// availability and vm options the gc uses major gc manager or minor gc
-// manager or both. The type of gc manager depends on the generation kind.
-// For DefNew and ParNew generation doing scavenge gc uses minor gc manager (so
-// _fullGC is set to false ) and for other generation kinds doing
-// mark-sweep-compact uses major gc manager (so _fullGC is set to true).
-TraceMemoryManagerStats::TraceMemoryManagerStats(Generation::Name kind, GCCause::Cause cause) {
-  switch (kind) {
-    case Generation::DefNew:
-#if INCLUDE_ALL_GCS
-    case Generation::ParNew:
-#endif // INCLUDE_ALL_GCS
-      _fullGC = false;
-      break;
-    case Generation::MarkSweepCompact:
-#if INCLUDE_ALL_GCS
-    case Generation::ConcurrentMarkSweep:
-#endif // INCLUDE_ALL_GCS
-      _fullGC = true;
-      break;
-    default:
-      _fullGC = false;
-      assert(false, "Unrecognized gc generation kind.");
-  }
-  // this has to be called in a stop the world pause and represent
-  // an entire gc pause, start to finish:
-  initialize(_fullGC, cause, true, true, true, true, true, true, true);
-}
-
-TraceMemoryManagerStats::TraceMemoryManagerStats(bool fullGC,
+TraceMemoryManagerStats::TraceMemoryManagerStats(GCMemoryManager* gc_memory_manager,
                                                  GCCause::Cause cause,
                                                  bool recordGCBeginTime,
                                                  bool recordPreGCUsage,
@@ -589,14 +243,14 @@
                                                  bool recordAccumulatedGCTime,
                                                  bool recordGCEndTime,
                                                  bool countCollection) {
-  initialize(fullGC, cause, recordGCBeginTime, recordPreGCUsage, recordPeakUsage,
+  initialize(gc_memory_manager, cause, recordGCBeginTime, recordPreGCUsage, recordPeakUsage,
              recordPostGCUsage, recordAccumulatedGCTime, recordGCEndTime,
              countCollection);
 }
 
 // for a subclass to create then initialize an instance before invoking
 // the MemoryService
-void TraceMemoryManagerStats::initialize(bool fullGC,
+void TraceMemoryManagerStats::initialize(GCMemoryManager* gc_memory_manager,
                                          GCCause::Cause cause,
                                          bool recordGCBeginTime,
                                          bool recordPreGCUsage,
@@ -605,7 +259,7 @@
                                          bool recordAccumulatedGCTime,
                                          bool recordGCEndTime,
                                          bool countCollection) {
-  _fullGC = fullGC;
+  _gc_memory_manager = gc_memory_manager;
   _recordGCBeginTime = recordGCBeginTime;
   _recordPreGCUsage = recordPreGCUsage;
   _recordPeakUsage = recordPeakUsage;
@@ -615,11 +269,11 @@
   _countCollection = countCollection;
   _cause = cause;
 
-  MemoryService::gc_begin(_fullGC, _recordGCBeginTime, _recordAccumulatedGCTime,
+  MemoryService::gc_begin(_gc_memory_manager, _recordGCBeginTime, _recordAccumulatedGCTime,
                           _recordPreGCUsage, _recordPeakUsage);
 }
 
 TraceMemoryManagerStats::~TraceMemoryManagerStats() {
-  MemoryService::gc_end(_fullGC, _recordPostGCUsage, _recordAccumulatedGCTime,
+  MemoryService::gc_end(_gc_memory_manager, _recordPostGCUsage, _recordAccumulatedGCTime,
                         _recordGCEndTime, _countCollection, _cause);
 }
--- a/src/hotspot/share/services/memoryService.hpp	Thu Nov 30 08:35:33 2017 -0800
+++ b/src/hotspot/share/services/memoryService.hpp	Thu Nov 30 13:40:07 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -26,7 +26,6 @@
 #define SHARE_VM_SERVICES_MEMORYSERVICE_HPP
 
 #include "gc/shared/gcCause.hpp"
-#include "gc/shared/generation.hpp"
 #include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "runtime/handles.hpp"
@@ -37,16 +36,7 @@
 class MemoryManager;
 class GCMemoryManager;
 class CollectedHeap;
-class Generation;
-class DefNewGeneration;
-class PSYoungGen;
-class PSOldGen;
 class CodeHeap;
-class ContiguousSpace;
-class CompactibleFreeListSpace;
-class GenCollectedHeap;
-class ParallelScavengeHeap;
-class G1CollectedHeap;
 
 // VM Monitoring and Management Support
 
@@ -61,10 +51,6 @@
   static GrowableArray<MemoryPool*>*    _pools_list;
   static GrowableArray<MemoryManager*>* _managers_list;
 
-  // memory managers for minor and major GC statistics
-  static GCMemoryManager*               _major_gc_manager;
-  static GCMemoryManager*               _minor_gc_manager;
-
   // memory manager and code heap pools for the CodeCache
   static MemoryManager*                 _code_cache_manager;
   static GrowableArray<MemoryPool*>*    _code_heap_pools;
@@ -72,51 +58,6 @@
   static MemoryPool*                    _metaspace_pool;
   static MemoryPool*                    _compressed_class_pool;
 
-  static void add_generation_memory_pool(Generation* gen,
-                                         MemoryManager* major_mgr,
-                                         MemoryManager* minor_mgr);
-  static void add_generation_memory_pool(Generation* gen,
-                                         MemoryManager* major_mgr) {
-    add_generation_memory_pool(gen, major_mgr, NULL);
-  }
-
-
-  static void add_psYoung_memory_pool(PSYoungGen* young_gen,
-                                      MemoryManager* major_mgr,
-                                      MemoryManager* minor_mgr);
-  static void add_psOld_memory_pool(PSOldGen* old_gen,
-                                    MemoryManager* mgr);
-
-  static void add_g1YoungGen_memory_pool(G1CollectedHeap* g1h,
-                                         MemoryManager* major_mgr,
-                                         MemoryManager* minor_mgr);
-  static void add_g1OldGen_memory_pool(G1CollectedHeap* g1h,
-                                       MemoryManager* mgr);
-
-  static MemoryPool* add_space(ContiguousSpace* space,
-                               const char* name,
-                               bool is_heap,
-                               size_t max_size,
-                               bool support_usage_threshold);
-  static MemoryPool* add_survivor_spaces(DefNewGeneration* young_gen,
-                                         const char* name,
-                                         bool is_heap,
-                                         size_t max_size,
-                                         bool support_usage_threshold);
-  static MemoryPool* add_gen(Generation* gen,
-                             const char* name,
-                             bool is_heap,
-                             bool support_usage_threshold);
-  static MemoryPool* add_cms_space(CompactibleFreeListSpace* space,
-                                   const char* name,
-                                   bool is_heap,
-                                   size_t max_size,
-                                   bool support_usage_threshold);
-
-  static void add_gen_collected_heap_info(GenCollectedHeap* heap);
-  static void add_parallel_scavenge_heap_info(ParallelScavengeHeap* heap);
-  static void add_g1_heap_info(G1CollectedHeap* g1h);
-
 public:
   static void set_universe_heap(CollectedHeap* heap);
   static void add_code_heap_memory_pool(CodeHeap* heap, const char* name);
@@ -155,10 +96,10 @@
   }
   static void track_memory_pool_usage(MemoryPool* pool);
 
-  static void gc_begin(bool fullGC, bool recordGCBeginTime,
+  static void gc_begin(GCMemoryManager* manager, bool recordGCBeginTime,
                        bool recordAccumulatedGCTime,
                        bool recordPreGCUsage, bool recordPeakUsage);
-  static void gc_end(bool fullGC, bool recordPostGCUsage,
+  static void gc_end(GCMemoryManager* manager, bool recordPostGCUsage,
                      bool recordAccumulatedGCTime,
                      bool recordGCEndTime, bool countCollection,
                      GCCause::Cause cause);
@@ -170,19 +111,11 @@
 
   // Create an instance of java/lang/management/MemoryUsage
   static Handle create_MemoryUsage_obj(MemoryUsage usage, TRAPS);
-
-  static const GCMemoryManager* get_minor_gc_manager() {
-      return _minor_gc_manager;
-  }
-
-  static const GCMemoryManager* get_major_gc_manager() {
-      return _major_gc_manager;
-  }
 };
 
 class TraceMemoryManagerStats : public StackObj {
 private:
-  bool         _fullGC;
+  GCMemoryManager* _gc_memory_manager;
   bool         _recordGCBeginTime;
   bool         _recordPreGCUsage;
   bool         _recordPeakUsage;
@@ -193,7 +126,7 @@
   GCCause::Cause _cause;
 public:
   TraceMemoryManagerStats() {}
-  TraceMemoryManagerStats(bool fullGC,
+  TraceMemoryManagerStats(GCMemoryManager* gc_memory_manager,
                           GCCause::Cause cause,
                           bool recordGCBeginTime = true,
                           bool recordPreGCUsage = true,
@@ -203,7 +136,7 @@
                           bool recordGCEndTime = true,
                           bool countCollection = true);
 
-  void initialize(bool fullGC,
+  void initialize(GCMemoryManager* gc_memory_manager,
                   GCCause::Cause cause,
                   bool recordGCBeginTime,
                   bool recordPreGCUsage,
@@ -213,7 +146,6 @@
                   bool recordGCEndTime,
                   bool countCollection);
 
-  TraceMemoryManagerStats(Generation::Name kind, GCCause::Cause cause);
   ~TraceMemoryManagerStats();
 };
 
--- a/src/hotspot/share/services/psMemoryPool.cpp	Thu Nov 30 08:35:33 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2007, 2015, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "classfile/systemDictionary.hpp"
-#include "classfile/vmSymbols.hpp"
-#include "oops/oop.inline.hpp"
-#include "runtime/handles.inline.hpp"
-#include "runtime/javaCalls.hpp"
-#include "services/lowMemoryDetector.hpp"
-#include "services/management.hpp"
-#include "services/memoryManager.hpp"
-#include "services/psMemoryPool.hpp"
-
-PSGenerationPool::PSGenerationPool(PSOldGen* old_gen,
-                                   const char* name,
-                                   PoolType type,
-                                   bool support_usage_threshold) :
-  CollectedMemoryPool(name, type, old_gen->capacity_in_bytes(),
-                      old_gen->reserved().byte_size(), support_usage_threshold), _old_gen(old_gen) {
-}
-
-MemoryUsage PSGenerationPool::get_memory_usage() {
-  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
-  size_t used      = used_in_bytes();
-  size_t committed = _old_gen->capacity_in_bytes();
-
-  return MemoryUsage(initial_size(), used, committed, maxSize);
-}
-
-// The max size of EdenMutableSpacePool =
-//     max size of the PSYoungGen - capacity of two survivor spaces
-//
-// Max size of PS eden space is changing due to ergonomic.
-// PSYoungGen, PSOldGen, Eden, Survivor spaces are all resizable.
-//
-EdenMutableSpacePool::EdenMutableSpacePool(PSYoungGen* young_gen,
-                                           MutableSpace* space,
-                                           const char* name,
-                                           PoolType type,
-                                           bool support_usage_threshold) :
-  CollectedMemoryPool(name, type, space->capacity_in_bytes(),
-                      (young_gen->max_size() - young_gen->from_space()->capacity_in_bytes() - young_gen->to_space()->capacity_in_bytes()),
-                       support_usage_threshold),
-  _young_gen(young_gen),
-  _space(space) {
-}
-
-MemoryUsage EdenMutableSpacePool::get_memory_usage() {
-  size_t maxSize   = (available_for_allocation() ? max_size() : 0);
-  size_t used = used_in_bytes();
-  size_t committed = _space->capacity_in_bytes();
-
-  return MemoryUsage(initial_size(), used, committed, maxSize);
-}
-
-// The max size of SurvivorMutableSpacePool =
-//     current capacity of the from-space
-//
-// PS from and to survivor spaces could have different sizes.
-//
-SurvivorMutableSpacePool::SurvivorMutableSpacePool(PSYoungGen* young_gen,
-                                                   const char* name,
-                                                   PoolType type,
-                                                   bool support_usage_threshold) :
-  CollectedMemoryPool(name, type, young_gen->from_space()->capacity_in_bytes(),
-                      young_gen->from_space()->capacity_in_bytes(),
-                      support_usage_threshold), _young_gen(young_gen) {
-}
-
-MemoryUsage SurvivorMutableSpacePool::get_memory_usage() {
-  size_t maxSize = (available_for_allocation() ? max_size() : 0);
-  size_t used    = used_in_bytes();
-  size_t committed = committed_in_bytes();
-  return MemoryUsage(initial_size(), used, committed, maxSize);
-}
--- a/src/hotspot/share/services/psMemoryPool.hpp	Thu Nov 30 08:35:33 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2007, 2015, 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_VM_SERVICES_PSMEMORYPOOL_HPP
-#define SHARE_VM_SERVICES_PSMEMORYPOOL_HPP
-
-#include "utilities/macros.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc/parallel/mutableSpace.hpp"
-#include "gc/parallel/psOldGen.hpp"
-#include "gc/parallel/psYoungGen.hpp"
-#include "gc/serial/defNewGeneration.hpp"
-#include "gc/shared/space.hpp"
-#include "memory/heap.hpp"
-#include "services/memoryPool.hpp"
-#include "services/memoryUsage.hpp"
-#endif // INCLUDE_ALL_GCS
-
-class PSGenerationPool : public CollectedMemoryPool {
-private:
-  PSOldGen* _old_gen;
-
-public:
-  PSGenerationPool(PSOldGen* pool, const char* name, PoolType type, bool support_usage_threshold);
-
-  MemoryUsage get_memory_usage();
-  size_t used_in_bytes()              { return _old_gen->used_in_bytes(); }
-  size_t max_size() const             { return _old_gen->reserved().byte_size(); }
-};
-
-class EdenMutableSpacePool : public CollectedMemoryPool {
-private:
-  PSYoungGen*   _young_gen;
-  MutableSpace* _space;
-
-public:
-  EdenMutableSpacePool(PSYoungGen* young_gen,
-                       MutableSpace* space,
-                       const char* name,
-                       PoolType type,
-                       bool support_usage_threshold);
-
-  MutableSpace* space()                     { return _space; }
-  MemoryUsage get_memory_usage();
-  size_t used_in_bytes()                    { return space()->used_in_bytes(); }
-  size_t max_size() const {
-    // Eden's max_size = max_size of Young Gen - the current committed size of survivor spaces
-    return _young_gen->max_size() - _young_gen->from_space()->capacity_in_bytes() - _young_gen->to_space()->capacity_in_bytes();
-  }
-};
-
-class SurvivorMutableSpacePool : public CollectedMemoryPool {
-private:
-  PSYoungGen*   _young_gen;
-
-public:
-  SurvivorMutableSpacePool(PSYoungGen* young_gen,
-                           const char* name,
-                           PoolType type,
-                           bool support_usage_threshold);
-
-  MemoryUsage get_memory_usage();
-
-  size_t used_in_bytes() {
-    return _young_gen->from_space()->used_in_bytes();
-  }
-  size_t committed_in_bytes() {
-    return _young_gen->from_space()->capacity_in_bytes();
-  }
-  size_t max_size() const {
-    // Return current committed size of the from-space
-    return _young_gen->from_space()->capacity_in_bytes();
-  }
-};
-
-#endif // SHARE_VM_SERVICES_PSMEMORYPOOL_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/TestMemoryMXBeansAndPoolsPresence.java	Thu Nov 30 13:40:07 2017 +0100
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.util.List;
+import java.util.ArrayList;
+import java.lang.management.*;
+import static jdk.test.lib.Asserts.*;
+import java.util.stream.*;
+
+/* @test TestMemoryMXBeansAndPoolsPresence
+ * @bug 8191564
+ * @summary Tests that GarbageCollectorMXBeans and GC MemoryPools are created.
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @requires vm.gc == null
+ * @run main/othervm -XX:+UseG1GC TestMemoryMXBeansAndPoolsPresence G1
+ * @run main/othervm -XX:+UseConcMarkSweepGC TestMemoryMXBeansAndPoolsPresence CMS
+ * @run main/othervm -XX:+UseParallelGC TestMemoryMXBeansAndPoolsPresence Parallel
+ * @run main/othervm -XX:+UseSerialGC TestMemoryMXBeansAndPoolsPresence Serial
+ */
+
+class GCBeanDescription {
+    public String name;
+    public String[] poolNames;
+
+    public GCBeanDescription(String name, String[] poolNames) {
+        this.name = name;
+        this.poolNames = poolNames;
+    }
+}
+
+public class TestMemoryMXBeansAndPoolsPresence {
+    public static void test(GCBeanDescription... expectedBeans) {
+        List<MemoryPoolMXBean> memoryPools = ManagementFactory.getMemoryPoolMXBeans();
+
+        List<GarbageCollectorMXBean> gcBeans = ManagementFactory.getGarbageCollectorMXBeans();
+        assertEQ(expectedBeans.length, gcBeans.size());
+
+        for (GCBeanDescription desc : expectedBeans) {
+            List<GarbageCollectorMXBean> beans = gcBeans.stream()
+                                                        .filter(b -> b.getName().equals(desc.name))
+                                                        .collect(Collectors.toList());
+            assertEQ(beans.size(), 1);
+
+            GarbageCollectorMXBean bean = beans.get(0);
+            assertEQ(desc.name, bean.getName());
+
+            String[] pools = bean.getMemoryPoolNames();
+            assertEQ(desc.poolNames.length, pools.length);
+            for (int i = 0; i < desc.poolNames.length; i++) {
+                assertEQ(desc.poolNames[i], pools[i]);
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        switch (args[0]) {
+            case "G1":
+                test(new GCBeanDescription("G1 Young Generation", new String[] {"G1 Eden Space", "G1 Survivor Space"}),
+                     new GCBeanDescription("G1 Old Generation",   new String[] {"G1 Eden Space", "G1 Survivor Space", "G1 Old Gen"}));
+                break;
+            case "CMS":
+                test(new GCBeanDescription("ParNew",              new String[] {"Par Eden Space", "Par Survivor Space"}),
+                     new GCBeanDescription("ConcurrentMarkSweep", new String[] {"Par Eden Space", "Par Survivor Space", "CMS Old Gen"}));
+                break;
+            case "Parallel":
+                test(new GCBeanDescription("PS Scavenge",         new String[] {"PS Eden Space", "PS Survivor Space"}),
+                     new GCBeanDescription("PS MarkSweep",        new String[] {"PS Eden Space", "PS Survivor Space", "PS Old Gen"}));
+                break;
+            case "Serial":
+                test(new GCBeanDescription("Copy",              new String[] {"Eden Space", "Survivor Space"}),
+                     new GCBeanDescription("MarkSweepCompact",  new String[] {"Eden Space", "Survivor Space", "Tenured Gen"}));
+                break;
+            default:
+                assertTrue(false);
+                break;
+
+        }
+    }
+}