8191564: Refactor GC related servicability code into GC specific subclasses
Reviewed-by: ehelin, eosterlund
--- 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), _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();
-SerialHeap::SerialHeap(GenCollectorPolicy* policy) : GenCollectedHeap(policy) {}
+ // 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();
-}
-
-// 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 (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;
-}
+ 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);
-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 (count > 0) {
+ gc_manager->set_num_gc_threads(count);
}
-
-#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;
+
+ }
+ }
+}