8191564: Refactor GC related servicability code into GC specific subclasses

Reviewed-by: ehelin, eosterlund
This commit is contained in:
Roman Kennke 2017-11-30 13:40:07 +01:00
parent d6aded9c68
commit 3f3f0cb67e
35 changed files with 678 additions and 817 deletions

View File

@ -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 @@ jint CMSHeap::initialize() {
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 @@ void CMSHeap::gc_epilogue(bool full) {
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;
}

View File

@ -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 @@ public:
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 @@ public:
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(); }

View File

@ -8116,42 +8116,42 @@ size_t MarkDeadObjectsClosure::do_blk(HeapWord* addr) {
}
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:

View File

@ -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 @@ bool G1CollectedHeap::do_full_collection(bool explicit_gc,
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 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* collector_policy) :
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 @@ jint G1CollectedHeap::initialize() {
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 @@ size_t G1CollectedHeap::conservative_max_heap_alignment() {
}
void G1CollectedHeap::post_initialize() {
CollectedHeap::post_initialize();
ref_processing_init();
}
@ -2954,7 +2975,7 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
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 @@ void G1CollectedHeap::rebuild_strong_code_roots() {
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;
}

View File

@ -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 GenerationSpec;
class G1ParScanThreadState;
class G1ParScanThreadStateSet;
class G1ParScanThreadState;
class MemoryPool;
class ObjectClosure;
class SpaceClosure;
class CompactibleSpaceClosure;
@ -149,6 +151,13 @@ private:
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 @@ private:
// 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 @@ public:
// 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; }

View File

@ -71,9 +71,9 @@ ReferenceProcessor* G1FullCollector::reference_processor() {
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),

View File

@ -39,6 +39,7 @@ class G1CMBitMap;
class G1FullGCMarker;
class G1FullGCScope;
class G1FullGCCompactionPoint;
class GCMemoryManager;
class ReferenceProcessor;
// The G1FullCollector holds data associated with the current Full GC.
@ -56,7 +57,7 @@ class G1FullCollector : StackObj {
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();

View File

@ -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 @@ G1FullGCScope::G1FullGCScope(bool explicit_gc, bool clear_soft) :
_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();

View File

@ -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 @@ class G1FullGCScope : public StackObj {
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();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* 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
@ -24,8 +24,8 @@
#include "precompiled.hpp"
#include "gc/g1/g1CollectedHeap.hpp"
#include "gc/g1/g1MemoryPool.hpp"
#include "gc/g1/heapRegion.hpp"
#include "services/g1MemoryPool.hpp"
G1MemoryPoolSuper::G1MemoryPoolSuper(G1CollectedHeap* g1h,
const char* name,
@ -33,7 +33,6 @@ G1MemoryPoolSuper::G1MemoryPoolSuper(G1CollectedHeap* g1h,
size_t max_size,
bool support_usage_threshold) :
_g1mm(g1h->g1mm()), CollectedMemoryPool(name,
MemoryPool::Heap,
init_size,
max_size,
support_usage_threshold) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* 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
@ -22,15 +22,12 @@
*
*/
#ifndef SHARE_VM_SERVICES_G1MEMORYPOOL_HPP
#define SHARE_VM_SERVICES_G1MEMORYPOOL_HPP
#ifndef SHARE_VM_GC_G1_G1MEMORYPOOL_HPP
#define SHARE_VM_GC_G1_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
@ -50,6 +47,8 @@
// on this model.
//
class G1CollectedHeap;
// This class is shared by the three G1 memory pool classes
// (G1EdenPool, G1SurvivorPool, G1OldGenPool).
class G1MemoryPoolSuper : public CollectedMemoryPool {
@ -107,4 +106,4 @@ public:
MemoryUsage get_memory_usage();
};
#endif // SHARE_VM_SERVICES_G1MEMORYPOOL_HPP
#endif // SHARE_VM_GC_G1_G1MEMORYPOOL_HPP

View File

@ -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 @@ jint ParallelScavengeHeap::initialize() {
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::register_nmethod(nmethod* nm) {
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;
}

View File

@ -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 @@ class ParallelScavengeHeap : public CollectedHeap {
// 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 @@ class ParallelScavengeHeap : public CollectedHeap {
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 @@ class ParallelScavengeHeap : public CollectedHeap {
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

View File

@ -172,7 +172,7 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
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();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* 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
@ -23,21 +23,12 @@
*/
#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"
#include "gc/parallel/psMemoryPool.hpp"
PSGenerationPool::PSGenerationPool(PSOldGen* old_gen,
const char* name,
PoolType type,
bool support_usage_threshold) :
CollectedMemoryPool(name, type, old_gen->capacity_in_bytes(),
CollectedMemoryPool(name, old_gen->capacity_in_bytes(),
old_gen->reserved().byte_size(), support_usage_threshold), _old_gen(old_gen) {
}
@ -58,9 +49,8 @@ MemoryUsage PSGenerationPool::get_memory_usage() {
EdenMutableSpacePool::EdenMutableSpacePool(PSYoungGen* young_gen,
MutableSpace* space,
const char* name,
PoolType type,
bool support_usage_threshold) :
CollectedMemoryPool(name, type, space->capacity_in_bytes(),
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),
@ -82,9 +72,8 @@ MemoryUsage EdenMutableSpacePool::get_memory_usage() {
//
SurvivorMutableSpacePool::SurvivorMutableSpacePool(PSYoungGen* young_gen,
const char* name,
PoolType type,
bool support_usage_threshold) :
CollectedMemoryPool(name, type, young_gen->from_space()->capacity_in_bytes(),
CollectedMemoryPool(name, young_gen->from_space()->capacity_in_bytes(),
young_gen->from_space()->capacity_in_bytes(),
support_usage_threshold), _young_gen(young_gen) {
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* 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
@ -25,28 +25,22 @@
#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);
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(); }
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 {
@ -58,7 +52,6 @@ public:
EdenMutableSpacePool(PSYoungGen* young_gen,
MutableSpace* space,
const char* name,
PoolType type,
bool support_usage_threshold);
MutableSpace* space() { return _space; }
@ -77,7 +70,6 @@ private:
public:
SurvivorMutableSpacePool(PSYoungGen* young_gen,
const char* name,
PoolType type,
bool support_usage_threshold);
MemoryUsage get_memory_usage();

View File

@ -1772,7 +1772,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
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();

View File

@ -305,7 +305,7 @@ bool PSScavenge::invoke_no_policy() {
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();

View File

@ -23,9 +23,44 @@
*/
#include "precompiled.hpp"
#include "gc/serial/defNewGeneration.hpp"
#include "gc/serial/serialHeap.hpp"
#include "gc/shared/genMemoryPools.hpp"
#include "services/memoryManager.hpp"
SerialHeap::SerialHeap(GenCollectorPolicy* policy) : GenCollectedHeap(policy) {}
SerialHeap::SerialHeap(GenCollectorPolicy* policy) :
GenCollectedHeap(policy), _eden_pool(NULL), _survivor_pool(NULL), _old_pool(NULL) {
_young_manager = new GCMemoryManager("Copy", "end of minor GC");
_old_manager = new GCMemoryManager("MarkSweepCompact", "end of major GC");
}
void SerialHeap::initialize_serviceability() {
DefNewGeneration* young = (DefNewGeneration*) young_gen();
// Add a memory pool for each space and young gen doesn't
// support low memory detection as it is expected to get filled up.
_eden_pool = new ContiguousSpacePool(young->eden(),
"Eden Space",
young->max_eden_size(),
false /* support_usage_threshold */);
_survivor_pool = new SurvivorContiguousSpacePool(young,
"Survivor Space",
young->max_survivor_size(),
false /* support_usage_threshold */);
Generation* old = old_gen();
_old_pool = new GenerationPool(old, "Tenured Gen", true);
_young_manager->add_pool(_eden_pool);
_young_manager->add_pool(_survivor_pool);
young->set_gc_manager(_young_manager);
_old_manager->add_pool(_eden_pool);
_old_manager->add_pool(_survivor_pool);
_old_manager->add_pool(_old_pool);
old->set_gc_manager(_old_manager);
}
void SerialHeap::check_gen_kinds() {
assert(young_gen()->kind() == Generation::DefNew,
@ -33,3 +68,18 @@ void SerialHeap::check_gen_kinds() {
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;
}

View File

@ -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 @@ public:
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 @@ public:
virtual bool card_mark_must_follow_store() const {
return false;
}
};
#endif // SHARE_VM_GC_CMS_CMSHEAP_HPP

View File

@ -611,3 +611,7 @@ void CollectedHeap::initialize_reserved_region(HeapWord *start, HeapWord *end) {
_reserved.set_start(start);
_reserved.set_end(end);
}
void CollectedHeap::post_initialize() {
initialize_serviceability();
}

View File

@ -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 CollectorPolicy;
class GCHeapSummary;
class GCTimer;
class GCTracer;
class GCMemoryManager;
class MemoryPool;
class MetaspaceSummary;
class Thread;
class ThreadClosure;
@ -217,7 +220,7 @@ class CollectedHeap : public CHeapObj<mtInternal> {
// 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 @@ class CollectedHeap : public CHeapObj<mtInternal> {
// 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 @@ class CollectedHeap : public CHeapObj<mtInternal> {
// 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);

View File

@ -143,6 +143,7 @@ char* GenCollectedHeap::allocate(size_t alignment,
}
void GenCollectedHeap::post_initialize() {
CollectedHeap::post_initialize();
ref_processing_init();
check_gen_kinds();
DefNewGeneration* def_new_gen = (DefNewGeneration*)_young_gen;
@ -270,7 +271,7 @@ void GenCollectedHeap::collect_generation(Generation* gen, bool full, size_t siz
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();

View File

@ -112,6 +112,9 @@ protected:
// (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,

View File

@ -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);
}

View File

@ -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

View File

@ -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");

View File

@ -58,6 +58,7 @@
//
class DefNewGeneration;
class GCMemoryManager;
class GenerationSpec;
class CompactibleSpace;
class ContiguousSpace;
@ -86,6 +87,8 @@ class Generation: public CHeapObj<mtGC> {
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 @@ public:
// 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

View File

@ -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 @@ void MemoryManager::add_pool(MemoryPool* pool) {
}
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 @@ void GCStatInfo::clear() {
}
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 @@ void GCMemoryManager::gc_end(bool recordPostGCUsage,
}
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));
}
}
}

View File

@ -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 @@ private:
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 @@ public:
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 @@ public:
// 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 @@ private:
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 @@ public:
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

View File

@ -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 @@ void MemoryPool::oops_do(OopClosure* f) {
}
}
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) {

View File

@ -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 MemoryPool : public CHeapObj<mtInternal> {
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;

View File

@ -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 GcThreadCountClosure::do_thread(Thread* thread) {
}
void MemoryService::set_universe_heap(CollectedHeap* heap) {
CollectedHeap::Name kind = heap->kind();
switch (kind) {
case CollectedHeap::SerialHeap :
case CollectedHeap::CMSHeap : {
add_gen_collected_heap_info(GenCollectedHeap::heap());
break;
}
#if INCLUDE_ALL_GCS
case CollectedHeap::ParallelScavengeHeap : {
add_parallel_scavenge_heap_info(ParallelScavengeHeap::heap());
break;
}
case CollectedHeap::G1CollectedHeap : {
add_g1_heap_info(G1CollectedHeap::heap());
break;
}
#endif // INCLUDE_ALL_GCS
default: {
guarantee(false, "Unrecognized kind of heap");
}
}
ResourceMark rm; // For internal allocations in GrowableArray.
GrowableArray<MemoryPool*> gc_mem_pools = heap->memory_pools();
_pools_list->appendAll(&gc_mem_pools);
// set the GC thread count
GcThreadCountClosure gctcc;
heap->gc_threads_do(&gctcc);
int count = gctcc.count();
if (count > 0) {
_minor_gc_manager->set_num_gc_threads(count);
_major_gc_manager->set_num_gc_threads(count);
}
// All memory pools and memory managers are initialized.
//
_minor_gc_manager->initialize_gc_stat_info();
_major_gc_manager->initialize_gc_stat_info();
}
GrowableArray<GCMemoryManager*> gc_memory_managers = heap->memory_managers();
for (int i = 0; i < gc_memory_managers.length(); i++) {
GCMemoryManager* gc_manager = gc_memory_managers.at(i);
// Add memory pools for GenCollectedHeap
// This function currently only supports two generations collected heap.
// The collector for GenCollectedHeap will have two memory managers.
void MemoryService::add_gen_collected_heap_info(GenCollectedHeap* heap) {
CollectorPolicy* policy = heap->collector_policy();
assert(policy->is_generation_policy(), "Only support two generations");
GenCollectorPolicy* gen_policy = policy->as_generation_policy();
if (gen_policy != NULL) {
Generation::Name kind = gen_policy->young_gen_spec()->name();
switch (kind) {
case Generation::DefNew:
_minor_gc_manager = MemoryManager::get_copy_memory_manager();
break;
#if INCLUDE_ALL_GCS
case Generation::ParNew:
_minor_gc_manager = MemoryManager::get_parnew_memory_manager();
break;
#endif // INCLUDE_ALL_GCS
default:
guarantee(false, "Unrecognized generation spec");
break;
}
if (policy->is_mark_sweep_policy()) {
_major_gc_manager = MemoryManager::get_msc_memory_manager();
#if INCLUDE_ALL_GCS
} else if (policy->is_concurrent_mark_sweep_policy()) {
_major_gc_manager = MemoryManager::get_cms_memory_manager();
#endif // INCLUDE_ALL_GCS
} else {
guarantee(false, "Unknown two-gen policy");
}
} else {
guarantee(false, "Non two-gen policy");
}
_managers_list->append(_minor_gc_manager);
_managers_list->append(_major_gc_manager);
add_generation_memory_pool(heap->young_gen(), _major_gc_manager, _minor_gc_manager);
add_generation_memory_pool(heap->old_gen(), _major_gc_manager);
}
#if INCLUDE_ALL_GCS
// Add memory pools for ParallelScavengeHeap
// This function currently only supports two generations collected heap.
// The collector for ParallelScavengeHeap will have two memory managers.
void MemoryService::add_parallel_scavenge_heap_info(ParallelScavengeHeap* heap) {
// Two managers to keep statistics about _minor_gc_manager and _major_gc_manager GC.
_minor_gc_manager = MemoryManager::get_psScavenge_memory_manager();
_major_gc_manager = MemoryManager::get_psMarkSweep_memory_manager();
_managers_list->append(_minor_gc_manager);
_managers_list->append(_major_gc_manager);
add_psYoung_memory_pool(heap->young_gen(), _major_gc_manager, _minor_gc_manager);
add_psOld_memory_pool(heap->old_gen(), _major_gc_manager);
}
void MemoryService::add_g1_heap_info(G1CollectedHeap* g1h) {
assert(UseG1GC, "sanity");
_minor_gc_manager = MemoryManager::get_g1YoungGen_memory_manager();
_major_gc_manager = MemoryManager::get_g1OldGen_memory_manager();
_managers_list->append(_minor_gc_manager);
_managers_list->append(_major_gc_manager);
add_g1YoungGen_memory_pool(g1h, _major_gc_manager, _minor_gc_manager);
add_g1OldGen_memory_pool(g1h, _major_gc_manager);
}
#endif // INCLUDE_ALL_GCS
MemoryPool* MemoryService::add_gen(Generation* gen,
const char* name,
bool is_heap,
bool support_usage_threshold) {
MemoryPool::PoolType type = (is_heap ? MemoryPool::Heap : MemoryPool::NonHeap);
GenerationPool* pool = new GenerationPool(gen, name, type, support_usage_threshold);
_pools_list->append(pool);
return (MemoryPool*) pool;
}
MemoryPool* MemoryService::add_space(ContiguousSpace* space,
const char* name,
bool is_heap,
size_t max_size,
bool support_usage_threshold) {
MemoryPool::PoolType type = (is_heap ? MemoryPool::Heap : MemoryPool::NonHeap);
ContiguousSpacePool* pool = new ContiguousSpacePool(space, name, type, max_size, support_usage_threshold);
_pools_list->append(pool);
return (MemoryPool*) pool;
}
MemoryPool* MemoryService::add_survivor_spaces(DefNewGeneration* young_gen,
const char* name,
bool is_heap,
size_t max_size,
bool support_usage_threshold) {
MemoryPool::PoolType type = (is_heap ? MemoryPool::Heap : MemoryPool::NonHeap);
SurvivorContiguousSpacePool* pool = new SurvivorContiguousSpacePool(young_gen, name, type, max_size, support_usage_threshold);
_pools_list->append(pool);
return (MemoryPool*) pool;
}
#if INCLUDE_ALL_GCS
MemoryPool* MemoryService::add_cms_space(CompactibleFreeListSpace* space,
const char* name,
bool is_heap,
size_t max_size,
bool support_usage_threshold) {
MemoryPool::PoolType type = (is_heap ? MemoryPool::Heap : MemoryPool::NonHeap);
CompactibleFreeListSpacePool* pool = new CompactibleFreeListSpacePool(space, name, type, max_size, support_usage_threshold);
_pools_list->append(pool);
return (MemoryPool*) pool;
}
#endif // INCLUDE_ALL_GCS
// Add memory pool(s) for one generation
void MemoryService::add_generation_memory_pool(Generation* gen,
MemoryManager* major_mgr,
MemoryManager* minor_mgr) {
guarantee(gen != NULL, "No generation for memory pool");
Generation::Name kind = gen->kind();
int index = _pools_list->length();
switch (kind) {
case Generation::DefNew: {
assert(major_mgr != NULL && minor_mgr != NULL, "Should have two managers");
DefNewGeneration* young_gen = (DefNewGeneration*) gen;
// Add a memory pool for each space and young gen doesn't
// support low memory detection as it is expected to get filled up.
MemoryPool* eden = add_space(young_gen->eden(),
"Eden Space",
true, /* is_heap */
young_gen->max_eden_size(),
false /* support_usage_threshold */);
MemoryPool* survivor = add_survivor_spaces(young_gen,
"Survivor Space",
true, /* is_heap */
young_gen->max_survivor_size(),
false /* support_usage_threshold */);
break;
}
#if INCLUDE_ALL_GCS
case Generation::ParNew:
{
assert(major_mgr != NULL && minor_mgr != NULL, "Should have two managers");
// Add a memory pool for each space and young gen doesn't
// support low memory detection as it is expected to get filled up.
ParNewGeneration* parnew_gen = (ParNewGeneration*) gen;
MemoryPool* eden = add_space(parnew_gen->eden(),
"Par Eden Space",
true /* is_heap */,
parnew_gen->max_eden_size(),
false /* support_usage_threshold */);
MemoryPool* survivor = add_survivor_spaces(parnew_gen,
"Par Survivor Space",
true, /* is_heap */
parnew_gen->max_survivor_size(),
false /* support_usage_threshold */);
break;
}
#endif // INCLUDE_ALL_GCS
case Generation::MarkSweepCompact: {
assert(major_mgr != NULL && minor_mgr == NULL, "Should have only one manager");
add_gen(gen,
"Tenured Gen",
true, /* is_heap */
true /* support_usage_threshold */);
break;
}
#if INCLUDE_ALL_GCS
case Generation::ConcurrentMarkSweep:
{
assert(major_mgr != NULL && minor_mgr == NULL, "Should have only one manager");
ConcurrentMarkSweepGeneration* cms = (ConcurrentMarkSweepGeneration*) gen;
MemoryPool* pool = add_cms_space(cms->cmsSpace(),
"CMS Old Gen",
true, /* is_heap */
cms->reserved().byte_size(),
true /* support_usage_threshold */);
break;
}
#endif // INCLUDE_ALL_GCS
default:
assert(false, "should not reach here");
// no memory pool added for others
break;
}
assert(major_mgr != NULL, "Should have at least one manager");
// Link managers and the memory pools together
for (int i = index; i < _pools_list->length(); i++) {
MemoryPool* pool = _pools_list->at(i);
major_mgr->add_pool(pool);
if (minor_mgr != NULL) {
minor_mgr->add_pool(pool);
if (count > 0) {
gc_manager->set_num_gc_threads(count);
}
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::track_memory_pool_usage(MemoryPool* pool) {
}
}
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_begin(bool fullGC, bool recordGCBeginTime,
}
}
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 @@ Handle MemoryService::create_MemoryUsage_obj(MemoryUsage usage, TRAPS) {
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 @@ TraceMemoryManagerStats::TraceMemoryManagerStats(bool fullGC,
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 @@ void TraceMemoryManagerStats::initialize(bool fullGC,
bool recordAccumulatedGCTime,
bool recordGCEndTime,
bool countCollection) {
_fullGC = fullGC;
_gc_memory_manager = gc_memory_manager;
_recordGCBeginTime = recordGCBeginTime;
_recordPreGCUsage = recordPreGCUsage;
_recordPeakUsage = recordPeakUsage;
@ -615,11 +269,11 @@ void TraceMemoryManagerStats::initialize(bool fullGC,
_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);
}

View File

@ -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 MemoryPool;
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 @@ private:
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 @@ private:
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 @@ public:
}
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 @@ public:
// 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 @@ private:
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 @@ public:
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 @@ public:
bool recordGCEndTime,
bool countCollection);
TraceMemoryManagerStats(Generation::Name kind, GCCause::Cause cause);
~TraceMemoryManagerStats();
};

View File

@ -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;
}
}
}