6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
It introduces the necessary memory pools for G1. Reviewed-by: mchung, ysr
This commit is contained in:
parent
b5af9f3408
commit
9cf0c891d9
@ -928,6 +928,8 @@ void G1CollectedHeap::do_collection(bool full, bool clear_all_soft_refs,
|
||||
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
|
||||
TraceTime t(full ? "Full GC (System.gc())" : "Full GC", PrintGC, true, gclog_or_tty);
|
||||
|
||||
TraceMemoryManagerStats tms(true /* fullGC */);
|
||||
|
||||
double start = os::elapsedTime();
|
||||
g1_policy()->record_full_collection_start();
|
||||
|
||||
@ -1001,6 +1003,8 @@ void G1CollectedHeap::do_collection(bool full, bool clear_all_soft_refs,
|
||||
|
||||
COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
|
||||
|
||||
MemoryService::track_memory_usage();
|
||||
|
||||
if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) {
|
||||
HandleMark hm; // Discard invalid handles created during verification
|
||||
gclog_or_tty->print(" VerifyAfterGC:");
|
||||
@ -2645,6 +2649,8 @@ G1CollectedHeap::do_collection_pause_at_safepoint() {
|
||||
}
|
||||
|
||||
{
|
||||
ResourceMark rm;
|
||||
|
||||
char verbose_str[128];
|
||||
sprintf(verbose_str, "GC pause ");
|
||||
if (g1_policy()->in_young_gc_mode()) {
|
||||
@ -2663,7 +2669,8 @@ G1CollectedHeap::do_collection_pause_at_safepoint() {
|
||||
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
|
||||
TraceTime t(verbose_str, PrintGC && !PrintGCDetails, true, gclog_or_tty);
|
||||
|
||||
ResourceMark rm;
|
||||
TraceMemoryManagerStats tms(false /* fullGC */);
|
||||
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
|
||||
assert(Thread::current() == VMThread::vm_thread(), "should be in vm thread");
|
||||
guarantee(!is_gc_active(), "collection is not reentrant");
|
||||
@ -2859,6 +2866,8 @@ G1CollectedHeap::do_collection_pause_at_safepoint() {
|
||||
|
||||
assert(regions_accounted_for(), "Region leakage.");
|
||||
|
||||
MemoryService::track_memory_usage();
|
||||
|
||||
if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) {
|
||||
HandleMark hm; // Discard invalid handles created during verification
|
||||
gclog_or_tty->print(" VerifyAfterGC:");
|
||||
|
@ -222,6 +222,15 @@ g1MarkSweep.hpp oop.hpp
|
||||
g1MarkSweep.hpp timer.hpp
|
||||
g1MarkSweep.hpp universe.hpp
|
||||
|
||||
g1MemoryPool.cpp heapRegion.hpp
|
||||
g1MemoryPool.cpp g1CollectedHeap.inline.hpp
|
||||
g1MemoryPool.cpp g1CollectedHeap.hpp
|
||||
g1MemoryPool.cpp g1CollectorPolicy.hpp
|
||||
g1MemoryPool.cpp g1MemoryPool.hpp
|
||||
|
||||
g1MemoryPool.hpp memoryUsage.hpp
|
||||
g1MemoryPool.hpp memoryPool.hpp
|
||||
|
||||
g1OopClosures.inline.hpp concurrentMark.hpp
|
||||
g1OopClosures.inline.hpp g1OopClosures.hpp
|
||||
g1OopClosures.inline.hpp g1CollectedHeap.hpp
|
||||
@ -303,6 +312,8 @@ heapRegionSeq.inline.hpp heapRegionSeq.hpp
|
||||
|
||||
klass.hpp g1OopClosures.hpp
|
||||
|
||||
memoryService.cpp g1MemoryPool.hpp
|
||||
|
||||
ptrQueue.cpp allocation.hpp
|
||||
ptrQueue.cpp allocation.inline.hpp
|
||||
ptrQueue.cpp mutex.hpp
|
||||
|
153
hotspot/src/share/vm/services/g1MemoryPool.cpp
Normal file
153
hotspot/src/share/vm/services/g1MemoryPool.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*
|
||||
*/
|
||||
|
||||
# include "incls/_precompiled.incl"
|
||||
# include "incls/_g1MemoryPool.cpp.incl"
|
||||
|
||||
G1MemoryPoolSuper::G1MemoryPoolSuper(G1CollectedHeap* g1h,
|
||||
const char* name,
|
||||
size_t init_size,
|
||||
size_t max_size,
|
||||
bool support_usage_threshold) :
|
||||
_g1h(g1h), CollectedMemoryPool(name,
|
||||
MemoryPool::Heap,
|
||||
init_size,
|
||||
max_size,
|
||||
support_usage_threshold) {
|
||||
assert(UseG1GC, "sanity");
|
||||
}
|
||||
|
||||
// See the comment at the top of g1MemoryPool.hpp
|
||||
size_t G1MemoryPoolSuper::eden_space_committed(G1CollectedHeap* g1h) {
|
||||
return eden_space_used(g1h);
|
||||
}
|
||||
|
||||
// See the comment at the top of g1MemoryPool.hpp
|
||||
size_t G1MemoryPoolSuper::eden_space_used(G1CollectedHeap* g1h) {
|
||||
size_t young_list_length = g1h->young_list_length();
|
||||
size_t eden_used = young_list_length * HeapRegion::GrainBytes;
|
||||
size_t survivor_used = survivor_space_used(g1h);
|
||||
eden_used = subtract_up_to_zero(eden_used, survivor_used);
|
||||
return eden_used;
|
||||
}
|
||||
|
||||
// See the comment at the top of g1MemoryPool.hpp
|
||||
size_t G1MemoryPoolSuper::eden_space_max(G1CollectedHeap* g1h) {
|
||||
return eden_space_committed(g1h);
|
||||
}
|
||||
|
||||
// See the comment at the top of g1MemoryPool.hpp
|
||||
size_t G1MemoryPoolSuper::survivor_space_committed(G1CollectedHeap* g1h) {
|
||||
return survivor_space_used(g1h);
|
||||
}
|
||||
|
||||
// See the comment at the top of g1MemoryPool.hpp
|
||||
size_t G1MemoryPoolSuper::survivor_space_used(G1CollectedHeap* g1h) {
|
||||
size_t survivor_num = g1h->g1_policy()->recorded_survivor_regions();
|
||||
size_t survivor_used = survivor_num * HeapRegion::GrainBytes;
|
||||
return survivor_used;
|
||||
}
|
||||
|
||||
// See the comment at the top of g1MemoryPool.hpp
|
||||
size_t G1MemoryPoolSuper::survivor_space_max(G1CollectedHeap* g1h) {
|
||||
return survivor_space_committed(g1h);
|
||||
}
|
||||
|
||||
// See the comment at the top of g1MemoryPool.hpp
|
||||
size_t G1MemoryPoolSuper::old_space_committed(G1CollectedHeap* g1h) {
|
||||
size_t committed = overall_committed(g1h);
|
||||
size_t eden_committed = eden_space_committed(g1h);
|
||||
size_t survivor_committed = survivor_space_committed(g1h);
|
||||
committed = subtract_up_to_zero(committed, eden_committed);
|
||||
committed = subtract_up_to_zero(committed, survivor_committed);
|
||||
return committed;
|
||||
}
|
||||
|
||||
// See the comment at the top of g1MemoryPool.hpp
|
||||
size_t G1MemoryPoolSuper::old_space_used(G1CollectedHeap* g1h) {
|
||||
size_t used = overall_used(g1h);
|
||||
size_t eden_used = eden_space_used(g1h);
|
||||
size_t survivor_used = survivor_space_used(g1h);
|
||||
used = subtract_up_to_zero(used, eden_used);
|
||||
used = subtract_up_to_zero(used, survivor_used);
|
||||
return used;
|
||||
}
|
||||
|
||||
// See the comment at the top of g1MemoryPool.hpp
|
||||
size_t G1MemoryPoolSuper::old_space_max(G1CollectedHeap* g1h) {
|
||||
size_t max = g1h->g1_reserved_obj_bytes();
|
||||
size_t eden_max = eden_space_max(g1h);
|
||||
size_t survivor_max = survivor_space_max(g1h);
|
||||
max = subtract_up_to_zero(max, eden_max);
|
||||
max = subtract_up_to_zero(max, survivor_max);
|
||||
return max;
|
||||
}
|
||||
|
||||
G1EdenPool::G1EdenPool(G1CollectedHeap* g1h) :
|
||||
G1MemoryPoolSuper(g1h,
|
||||
"G1 Eden",
|
||||
eden_space_committed(g1h), /* init_size */
|
||||
eden_space_max(g1h), /* max_size */
|
||||
false /* support_usage_threshold */) {
|
||||
}
|
||||
|
||||
MemoryUsage G1EdenPool::get_memory_usage() {
|
||||
size_t maxSize = max_size();
|
||||
size_t used = used_in_bytes();
|
||||
size_t committed = eden_space_committed();
|
||||
|
||||
return MemoryUsage(initial_size(), used, committed, maxSize);
|
||||
}
|
||||
|
||||
G1SurvivorPool::G1SurvivorPool(G1CollectedHeap* g1h) :
|
||||
G1MemoryPoolSuper(g1h,
|
||||
"G1 Survivor",
|
||||
survivor_space_committed(g1h), /* init_size */
|
||||
survivor_space_max(g1h), /* max_size */
|
||||
false /* support_usage_threshold */) {
|
||||
}
|
||||
|
||||
MemoryUsage G1SurvivorPool::get_memory_usage() {
|
||||
size_t maxSize = max_size();
|
||||
size_t used = used_in_bytes();
|
||||
size_t committed = survivor_space_committed();
|
||||
|
||||
return MemoryUsage(initial_size(), used, committed, maxSize);
|
||||
}
|
||||
|
||||
G1OldGenPool::G1OldGenPool(G1CollectedHeap* g1h) :
|
||||
G1MemoryPoolSuper(g1h,
|
||||
"G1 Old Gen",
|
||||
old_space_committed(g1h), /* init_size */
|
||||
old_space_max(g1h), /* max_size */
|
||||
true /* support_usage_threshold */) {
|
||||
}
|
||||
|
||||
MemoryUsage G1OldGenPool::get_memory_usage() {
|
||||
size_t maxSize = max_size();
|
||||
size_t used = used_in_bytes();
|
||||
size_t committed = old_space_committed();
|
||||
|
||||
return MemoryUsage(initial_size(), used, committed, maxSize);
|
||||
}
|
226
hotspot/src/share/vm/services/g1MemoryPool.hpp
Normal file
226
hotspot/src/share/vm/services/g1MemoryPool.hpp
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*
|
||||
*/
|
||||
|
||||
class G1CollectedHeap;
|
||||
|
||||
// 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.
|
||||
//
|
||||
// The above approach inroduces a couple of challenging issues in the
|
||||
// implementation of the three memory pools:
|
||||
//
|
||||
// 1) The used space calculation for a pool is not necessarily
|
||||
// independent of the others. We can easily get from G1 the overall
|
||||
// used space in the entire heap, the number of regions in the young
|
||||
// generation (includes both eden and survivors), and the number of
|
||||
// survivor regions. So, from that we calculate:
|
||||
//
|
||||
// survivor_used = survivor_num * region_size
|
||||
// eden_used = young_region_num * region_size - survivor_used
|
||||
// old_gen_used = overall_used - eden_used - survivor_used
|
||||
//
|
||||
// Note that survivor_used and eden_used are upper bounds. To get the
|
||||
// actual value we would have to iterate over the regions and add up
|
||||
// ->used(). But that'd be expensive. So, we'll accept some lack of
|
||||
// accuracy for those two. But, we have to be careful when calculating
|
||||
// old_gen_used, in case we subtract from overall_used more then the
|
||||
// actual number and our result goes negative.
|
||||
//
|
||||
// 2) Calculating the used space is straightforward, as described
|
||||
// above. However, how do we calculate the committed space, given that
|
||||
// we allocate space for the eden, survivor, and old gen out of the
|
||||
// same pool of regions? One way to do this is to use the used value
|
||||
// as also the committed value for the eden and survivor spaces and
|
||||
// then calculate the old gen committed space as follows:
|
||||
//
|
||||
// old_gen_committed = overall_committed - eden_committed - survivor_committed
|
||||
//
|
||||
// Maybe a better way to do that would be to calculate used for eden
|
||||
// and survivor as a sum of ->used() over their regions and then
|
||||
// calculate committed as region_num * region_size (i.e., what we use
|
||||
// to calculate the used space now). This is something to consider
|
||||
// in the future.
|
||||
//
|
||||
// 3) Another decision that is again not straightforward is what is
|
||||
// the max size that each memory pool can grow to. Right now, we set
|
||||
// that the committed size for the eden and the survivors and
|
||||
// calculate the old gen max as follows (basically, it's a similar
|
||||
// pattern to what we use for the committed space, as described
|
||||
// above):
|
||||
//
|
||||
// old_gen_max = overall_max - eden_max - survivor_max
|
||||
//
|
||||
// 4) Now, there is a very subtle issue with all the above. The
|
||||
// framework will call get_memory_usage() on the three pools
|
||||
// asynchronously. As a result, each call might get a different value
|
||||
// for, say, survivor_num which will yield inconsistent values for
|
||||
// eden_used, survivor_used, and old_gen_used (as survivor_num is used
|
||||
// in the calculation of all three). This would normally be
|
||||
// ok. However, it's possible that this might cause the sum of
|
||||
// eden_used, survivor_used, and old_gen_used to go over the max heap
|
||||
// size and this seems to sometimes cause JConsole (and maybe other
|
||||
// clients) to get confused. There's not a really an easy / clean
|
||||
// solution to this problem, due to the asynchrounous nature of the
|
||||
// framework.
|
||||
|
||||
|
||||
// This class is shared by the three G1 memory pool classes
|
||||
// (G1EdenPool, G1SurvivorPool, G1OldGenPool). Given that the way we
|
||||
// calculate used / committed bytes for these three pools is related
|
||||
// (see comment above), we put the calculations in this class so that
|
||||
// we can easily share them among the subclasses.
|
||||
class G1MemoryPoolSuper : public CollectedMemoryPool {
|
||||
private:
|
||||
G1CollectedHeap* _g1h;
|
||||
|
||||
// It returns x - y if x > y, 0 otherwise.
|
||||
// As described in the comment above, some of the inputs to the
|
||||
// calculations we have to do are obtained concurrently and hence
|
||||
// may be inconsistent with each other. So, this provides a
|
||||
// defensive way of performing the subtraction and avoids the value
|
||||
// going negative (which would mean a very large result, given that
|
||||
// the parameter are size_t).
|
||||
static size_t subtract_up_to_zero(size_t x, size_t y) {
|
||||
if (x > y) {
|
||||
return x - y;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
// Would only be called from subclasses.
|
||||
G1MemoryPoolSuper(G1CollectedHeap* g1h,
|
||||
const char* name,
|
||||
size_t init_size,
|
||||
size_t max_size,
|
||||
bool support_usage_threshold);
|
||||
|
||||
// The reason why all the code is in static methods is so that it
|
||||
// can be safely called from the constructors of the subclasses.
|
||||
|
||||
static size_t overall_committed(G1CollectedHeap* g1h) {
|
||||
return g1h->capacity();
|
||||
}
|
||||
static size_t overall_used(G1CollectedHeap* g1h) {
|
||||
return g1h->used_unlocked();
|
||||
}
|
||||
|
||||
static size_t eden_space_committed(G1CollectedHeap* g1h);
|
||||
static size_t eden_space_used(G1CollectedHeap* g1h);
|
||||
static size_t eden_space_max(G1CollectedHeap* g1h);
|
||||
|
||||
static size_t survivor_space_committed(G1CollectedHeap* g1h);
|
||||
static size_t survivor_space_used(G1CollectedHeap* g1h);
|
||||
static size_t survivor_space_max(G1CollectedHeap* g1h);
|
||||
|
||||
static size_t old_space_committed(G1CollectedHeap* g1h);
|
||||
static size_t old_space_used(G1CollectedHeap* g1h);
|
||||
static size_t old_space_max(G1CollectedHeap* g1h);
|
||||
|
||||
// The non-static versions are included for convenience.
|
||||
|
||||
size_t eden_space_committed() {
|
||||
return eden_space_committed(_g1h);
|
||||
}
|
||||
size_t eden_space_used() {
|
||||
return eden_space_used(_g1h);
|
||||
}
|
||||
size_t eden_space_max() {
|
||||
return eden_space_max(_g1h);
|
||||
}
|
||||
|
||||
size_t survivor_space_committed() {
|
||||
return survivor_space_committed(_g1h);
|
||||
}
|
||||
size_t survivor_space_used() {
|
||||
return survivor_space_used(_g1h);
|
||||
}
|
||||
size_t survivor_space_max() {
|
||||
return survivor_space_max(_g1h);
|
||||
}
|
||||
|
||||
size_t old_space_committed() {
|
||||
return old_space_committed(_g1h);
|
||||
}
|
||||
size_t old_space_used() {
|
||||
return old_space_used(_g1h);
|
||||
}
|
||||
size_t old_space_max() {
|
||||
return old_space_max(_g1h);
|
||||
}
|
||||
};
|
||||
|
||||
// Memory pool that represents the G1 eden.
|
||||
class G1EdenPool : public G1MemoryPoolSuper {
|
||||
public:
|
||||
G1EdenPool(G1CollectedHeap* g1h);
|
||||
|
||||
size_t used_in_bytes() {
|
||||
return eden_space_used();
|
||||
}
|
||||
size_t max_size() {
|
||||
return eden_space_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 survivor_space_used();
|
||||
}
|
||||
size_t max_size() {
|
||||
return survivor_space_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 old_space_used();
|
||||
}
|
||||
size_t max_size() {
|
||||
return old_space_max();
|
||||
}
|
||||
MemoryUsage get_memory_usage();
|
||||
};
|
@ -72,6 +72,14 @@ 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();
|
||||
}
|
||||
|
||||
instanceOop MemoryManager::get_memory_manager_instance(TRAPS) {
|
||||
// Must do an acquire so as to force ordering of subsequent
|
||||
// loads from anything _memory_mgr_obj points to or implies.
|
||||
|
@ -54,7 +54,9 @@ public:
|
||||
ParNew,
|
||||
ConcurrentMarkSweep,
|
||||
PSScavenge,
|
||||
PSMarkSweep
|
||||
PSMarkSweep,
|
||||
G1YoungGen,
|
||||
G1OldGen
|
||||
};
|
||||
|
||||
MemoryManager();
|
||||
@ -85,6 +87,8 @@ public:
|
||||
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();
|
||||
|
||||
};
|
||||
|
||||
@ -231,3 +235,21 @@ public:
|
||||
MemoryManager::Name kind() { return MemoryManager::PSMarkSweep; }
|
||||
const char* name() { return "PS MarkSweep"; }
|
||||
};
|
||||
|
||||
class G1YoungGenMemoryManager : public GCMemoryManager {
|
||||
private:
|
||||
public:
|
||||
G1YoungGenMemoryManager() : GCMemoryManager() {}
|
||||
|
||||
MemoryManager::Name kind() { return MemoryManager::G1YoungGen; }
|
||||
const char* name() { return "G1 Young Generation"; }
|
||||
};
|
||||
|
||||
class G1OldGenMemoryManager : public GCMemoryManager {
|
||||
private:
|
||||
public:
|
||||
G1OldGenMemoryManager() : GCMemoryManager() {}
|
||||
|
||||
MemoryManager::Name kind() { return MemoryManager::G1OldGen; }
|
||||
const char* name() { return "G1 Old Generation"; }
|
||||
};
|
||||
|
@ -60,8 +60,8 @@ void MemoryService::set_universe_heap(CollectedHeap* heap) {
|
||||
break;
|
||||
}
|
||||
case CollectedHeap::G1CollectedHeap : {
|
||||
G1CollectedHeap::g1_unimplemented();
|
||||
return;
|
||||
add_g1_heap_info(G1CollectedHeap::heap());
|
||||
break;
|
||||
}
|
||||
#endif // SERIALGC
|
||||
default: {
|
||||
@ -164,6 +164,19 @@ void MemoryService::add_parallel_scavenge_heap_info(ParallelScavengeHeap* heap)
|
||||
add_psOld_memory_pool(heap->old_gen(), _major_gc_manager);
|
||||
add_psPerm_memory_pool(heap->perm_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);
|
||||
add_g1PermGen_memory_pool(g1h, _major_gc_manager);
|
||||
}
|
||||
#endif // SERIALGC
|
||||
|
||||
MemoryPool* MemoryService::add_gen(Generation* gen,
|
||||
@ -384,6 +397,64 @@ void MemoryService::add_psPerm_memory_pool(PSPermGen* gen, MemoryManager* mgr) {
|
||||
mgr->add_pool(perm_gen);
|
||||
_pools_list->append(perm_gen);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void MemoryService::add_g1PermGen_memory_pool(G1CollectedHeap* g1h,
|
||||
MemoryManager* mgr) {
|
||||
assert(mgr != NULL, "should have one manager");
|
||||
|
||||
CompactingPermGenGen* perm_gen = (CompactingPermGenGen*) g1h->perm_gen();
|
||||
PermanentGenerationSpec* spec = perm_gen->spec();
|
||||
size_t max_size = spec->max_size() - spec->read_only_size()
|
||||
- spec->read_write_size();
|
||||
MemoryPool* pool = add_space(perm_gen->unshared_space(),
|
||||
"G1 Perm Gen",
|
||||
false, /* is_heap */
|
||||
max_size,
|
||||
true /* support_usage_threshold */);
|
||||
mgr->add_pool(pool);
|
||||
|
||||
// in case we support CDS in G1
|
||||
if (UseSharedSpaces) {
|
||||
pool = add_space(perm_gen->ro_space(),
|
||||
"G1 Perm Gen [shared-ro]",
|
||||
false, /* is_heap */
|
||||
spec->read_only_size(),
|
||||
true /* support_usage_threshold */);
|
||||
mgr->add_pool(pool);
|
||||
|
||||
pool = add_space(perm_gen->rw_space(),
|
||||
"G1 Perm Gen [shared-rw]",
|
||||
false, /* is_heap */
|
||||
spec->read_write_size(),
|
||||
true /* support_usage_threshold */);
|
||||
mgr->add_pool(pool);
|
||||
}
|
||||
}
|
||||
#endif // SERIALGC
|
||||
|
||||
void MemoryService::add_code_heap_memory_pool(CodeHeap* heap) {
|
||||
|
@ -40,6 +40,7 @@ class GenCollectedHeap;
|
||||
class ParallelScavengeHeap;
|
||||
class CompactingPermGenGen;
|
||||
class CMSPermGenGen;
|
||||
class G1CollectedHeap;
|
||||
|
||||
// VM Monitoring and Management Support
|
||||
|
||||
@ -88,6 +89,13 @@ private:
|
||||
static void add_psPerm_memory_pool(PSPermGen* perm,
|
||||
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 void add_g1PermGen_memory_pool(G1CollectedHeap* g1h,
|
||||
MemoryManager* mgr);
|
||||
|
||||
static MemoryPool* add_space(ContiguousSpace* space,
|
||||
const char* name,
|
||||
@ -111,6 +119,7 @@ private:
|
||||
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user