7075646: G1: fix inconsistencies in the monitoring data
Fixed a few inconsistencies in the monitoring data, in particular when reported from jstat. Reviewed-by: jmasa, brutisso, johnc
This commit is contained in:
parent
1b62d10b4b
commit
55c503aea2
@ -816,6 +816,11 @@ HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size) {
|
||||
result =
|
||||
humongous_obj_allocate_initialize_regions(first, num_regions, word_size);
|
||||
assert(result != NULL, "it should always return a valid result");
|
||||
|
||||
// A successful humongous object allocation changes the used space
|
||||
// information of the old generation so we need to recalculate the
|
||||
// sizes and update the jstat counters here.
|
||||
g1mm()->update_sizes();
|
||||
}
|
||||
|
||||
verify_region_sets_optional();
|
||||
@ -1422,7 +1427,7 @@ bool G1CollectedHeap::do_collection(bool explicit_gc,
|
||||
if (PrintHeapAtGC) {
|
||||
Universe::print_heap_after_gc();
|
||||
}
|
||||
g1mm()->update_counters();
|
||||
g1mm()->update_sizes();
|
||||
post_full_gc_dump();
|
||||
|
||||
return true;
|
||||
@ -1790,6 +1795,7 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) :
|
||||
_evac_failure_scan_stack(NULL) ,
|
||||
_mark_in_progress(false),
|
||||
_cg1r(NULL), _summary_bytes_used(0),
|
||||
_g1mm(NULL),
|
||||
_refine_cte_cl(NULL),
|
||||
_full_collection(false),
|
||||
_free_list("Master Free List"),
|
||||
@ -2069,7 +2075,7 @@ jint G1CollectedHeap::initialize() {
|
||||
|
||||
// Do create of the monitoring and management support so that
|
||||
// values in the heap have been properly initialized.
|
||||
_g1mm = new G1MonitoringSupport(this, &_g1_storage);
|
||||
_g1mm = new G1MonitoringSupport(this);
|
||||
|
||||
return JNI_OK;
|
||||
}
|
||||
@ -3702,7 +3708,7 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
|
||||
if (PrintHeapAtGC) {
|
||||
Universe::print_heap_after_gc();
|
||||
}
|
||||
g1mm()->update_counters();
|
||||
g1mm()->update_sizes();
|
||||
|
||||
if (G1SummarizeRSetStats &&
|
||||
(G1SummarizeRSetStatsPeriod > 0) &&
|
||||
@ -5815,7 +5821,6 @@ HeapRegion* G1CollectedHeap::new_mutator_alloc_region(size_t word_size,
|
||||
g1_policy()->update_region_num(true /* next_is_young */);
|
||||
set_region_short_lived_locked(new_alloc_region);
|
||||
_hr_printer.alloc(new_alloc_region, G1HRPrinter::Eden, young_list_full);
|
||||
g1mm()->update_eden_counters();
|
||||
return new_alloc_region;
|
||||
}
|
||||
}
|
||||
@ -5830,6 +5835,10 @@ void G1CollectedHeap::retire_mutator_alloc_region(HeapRegion* alloc_region,
|
||||
g1_policy()->add_region_to_incremental_cset_lhs(alloc_region);
|
||||
_summary_bytes_used += allocated_bytes;
|
||||
_hr_printer.retire(alloc_region);
|
||||
// We update the eden sizes here, when the region is retired,
|
||||
// instead of when it's allocated, since this is the point that its
|
||||
// used space has been recored in _summary_bytes_used.
|
||||
g1mm()->update_eden_size();
|
||||
}
|
||||
|
||||
HeapRegion* MutatorAllocRegion::allocate_new_region(size_t word_size,
|
||||
|
@ -597,7 +597,10 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
G1MonitoringSupport* g1mm() { return _g1mm; }
|
||||
G1MonitoringSupport* g1mm() {
|
||||
assert(_g1mm != NULL, "should have been initialized");
|
||||
return _g1mm;
|
||||
}
|
||||
|
||||
// Expand the garbage-first heap by at least the given size (in bytes!).
|
||||
// Returns true if the heap was expanded by the requested amount;
|
||||
|
@ -1149,6 +1149,10 @@ public:
|
||||
return young_list_length < young_list_max_length;
|
||||
}
|
||||
|
||||
size_t young_list_max_length() {
|
||||
return _young_list_max_length;
|
||||
}
|
||||
|
||||
void update_region_num(bool young);
|
||||
|
||||
bool full_young_gcs() {
|
||||
|
@ -27,19 +27,69 @@
|
||||
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
|
||||
#include "gc_implementation/g1/g1CollectorPolicy.hpp"
|
||||
|
||||
G1MonitoringSupport::G1MonitoringSupport(G1CollectedHeap* g1h,
|
||||
VirtualSpace* g1_storage_addr) :
|
||||
G1GenerationCounters::G1GenerationCounters(G1MonitoringSupport* g1mm,
|
||||
const char* name,
|
||||
int ordinal, int spaces,
|
||||
size_t min_capacity,
|
||||
size_t max_capacity,
|
||||
size_t curr_capacity)
|
||||
: GenerationCounters(name, ordinal, spaces, min_capacity,
|
||||
max_capacity, curr_capacity), _g1mm(g1mm) { }
|
||||
|
||||
// We pad the capacity three times given that the young generation
|
||||
// contains three spaces (eden and two survivors).
|
||||
G1YoungGenerationCounters::G1YoungGenerationCounters(G1MonitoringSupport* g1mm,
|
||||
const char* name)
|
||||
: G1GenerationCounters(g1mm, name, 0 /* ordinal */, 3 /* spaces */,
|
||||
G1MonitoringSupport::pad_capacity(0, 3) /* min_capacity */,
|
||||
G1MonitoringSupport::pad_capacity(g1mm->young_gen_max(), 3),
|
||||
G1MonitoringSupport::pad_capacity(0, 3) /* curr_capacity */) {
|
||||
update_all();
|
||||
}
|
||||
|
||||
G1OldGenerationCounters::G1OldGenerationCounters(G1MonitoringSupport* g1mm,
|
||||
const char* name)
|
||||
: G1GenerationCounters(g1mm, name, 1 /* ordinal */, 1 /* spaces */,
|
||||
G1MonitoringSupport::pad_capacity(0) /* min_capacity */,
|
||||
G1MonitoringSupport::pad_capacity(g1mm->old_gen_max()),
|
||||
G1MonitoringSupport::pad_capacity(0) /* curr_capacity */) {
|
||||
update_all();
|
||||
}
|
||||
|
||||
void G1YoungGenerationCounters::update_all() {
|
||||
size_t committed =
|
||||
G1MonitoringSupport::pad_capacity(_g1mm->young_gen_committed(), 3);
|
||||
_current_size->set_value(committed);
|
||||
}
|
||||
|
||||
void G1OldGenerationCounters::update_all() {
|
||||
size_t committed =
|
||||
G1MonitoringSupport::pad_capacity(_g1mm->old_gen_committed());
|
||||
_current_size->set_value(committed);
|
||||
}
|
||||
|
||||
G1MonitoringSupport::G1MonitoringSupport(G1CollectedHeap* g1h) :
|
||||
_g1h(g1h),
|
||||
_incremental_collection_counters(NULL),
|
||||
_full_collection_counters(NULL),
|
||||
_non_young_collection_counters(NULL),
|
||||
_old_collection_counters(NULL),
|
||||
_old_space_counters(NULL),
|
||||
_young_collection_counters(NULL),
|
||||
_eden_counters(NULL),
|
||||
_from_counters(NULL),
|
||||
_to_counters(NULL),
|
||||
_g1_storage_addr(g1_storage_addr)
|
||||
{
|
||||
|
||||
_overall_reserved(0),
|
||||
_overall_committed(0), _overall_used(0),
|
||||
_young_region_num(0),
|
||||
_young_gen_committed(0),
|
||||
_eden_committed(0), _eden_used(0),
|
||||
_survivor_committed(0), _survivor_used(0),
|
||||
_old_committed(0), _old_used(0) {
|
||||
|
||||
_overall_reserved = g1h->max_capacity();
|
||||
recalculate_sizes();
|
||||
|
||||
// Counters for GC collections
|
||||
//
|
||||
// name "collector.0". In a generational collector this would be the
|
||||
@ -69,110 +119,147 @@ G1MonitoringSupport::G1MonitoringSupport(G1CollectedHeap* g1h,
|
||||
// generational GC terms. The "1, 1" parameters are for
|
||||
// the n-th generation (=1) with 1 space.
|
||||
// Counters are created from minCapacity, maxCapacity, and capacity
|
||||
_non_young_collection_counters =
|
||||
new GenerationCounters("whole heap", 1, 1, _g1_storage_addr);
|
||||
_old_collection_counters = new G1OldGenerationCounters(this, "old");
|
||||
|
||||
// name "generation.1.space.0"
|
||||
// Counters are created from maxCapacity, capacity, initCapacity,
|
||||
// and used.
|
||||
_old_space_counters = new HSpaceCounters("space", 0,
|
||||
_g1h->max_capacity(), _g1h->capacity(), _non_young_collection_counters);
|
||||
_old_space_counters = new HSpaceCounters("space", 0 /* ordinal */,
|
||||
pad_capacity(overall_reserved()) /* max_capacity */,
|
||||
pad_capacity(old_space_committed()) /* init_capacity */,
|
||||
_old_collection_counters);
|
||||
|
||||
// Young collection set
|
||||
// name "generation.0". This is logically the young generation.
|
||||
// The "0, 3" are paremeters for the n-th genertaion (=0) with 3 spaces.
|
||||
// See _non_young_collection_counters for additional counters
|
||||
_young_collection_counters = new GenerationCounters("young", 0, 3, NULL);
|
||||
// See _old_collection_counters for additional counters
|
||||
_young_collection_counters = new G1YoungGenerationCounters(this, "young");
|
||||
|
||||
// Replace "max_heap_byte_size() with maximum young gen size for
|
||||
// g1Collectedheap
|
||||
// name "generation.0.space.0"
|
||||
// See _old_space_counters for additional counters
|
||||
_eden_counters = new HSpaceCounters("eden", 0,
|
||||
_g1h->max_capacity(), eden_space_committed(),
|
||||
_eden_counters = new HSpaceCounters("eden", 0 /* ordinal */,
|
||||
pad_capacity(overall_reserved()) /* max_capacity */,
|
||||
pad_capacity(eden_space_committed()) /* init_capacity */,
|
||||
_young_collection_counters);
|
||||
|
||||
// name "generation.0.space.1"
|
||||
// See _old_space_counters for additional counters
|
||||
// Set the arguments to indicate that this survivor space is not used.
|
||||
_from_counters = new HSpaceCounters("s0", 1, (long) 0, (long) 0,
|
||||
_from_counters = new HSpaceCounters("s0", 1 /* ordinal */,
|
||||
pad_capacity(0) /* max_capacity */,
|
||||
pad_capacity(0) /* init_capacity */,
|
||||
_young_collection_counters);
|
||||
// Given that this survivor space is not used, we update it here
|
||||
// once to reflect that its used space is 0 so that we don't have to
|
||||
// worry about updating it again later.
|
||||
_from_counters->update_used(0);
|
||||
|
||||
// name "generation.0.space.2"
|
||||
// See _old_space_counters for additional counters
|
||||
_to_counters = new HSpaceCounters("s1", 2,
|
||||
_g1h->max_capacity(),
|
||||
survivor_space_committed(),
|
||||
_to_counters = new HSpaceCounters("s1", 2 /* ordinal */,
|
||||
pad_capacity(overall_reserved()) /* max_capacity */,
|
||||
pad_capacity(survivor_space_committed()) /* init_capacity */,
|
||||
_young_collection_counters);
|
||||
}
|
||||
|
||||
size_t G1MonitoringSupport::overall_committed() {
|
||||
return g1h()->capacity();
|
||||
void G1MonitoringSupport::recalculate_sizes() {
|
||||
G1CollectedHeap* g1 = g1h();
|
||||
|
||||
// Recalculate all the sizes from scratch. We assume that this is
|
||||
// called at a point where no concurrent updates to the various
|
||||
// values we read here are possible (i.e., at a STW phase at the end
|
||||
// of a GC).
|
||||
|
||||
size_t young_list_length = g1->young_list()->length();
|
||||
size_t survivor_list_length = g1->g1_policy()->recorded_survivor_regions();
|
||||
assert(young_list_length >= survivor_list_length, "invariant");
|
||||
size_t eden_list_length = young_list_length - survivor_list_length;
|
||||
// Max length includes any potential extensions to the young gen
|
||||
// we'll do when the GC locker is active.
|
||||
size_t young_list_max_length = g1->g1_policy()->young_list_max_length();
|
||||
assert(young_list_max_length >= survivor_list_length, "invariant");
|
||||
size_t eden_list_max_length = young_list_max_length - survivor_list_length;
|
||||
|
||||
_overall_used = g1->used_unlocked();
|
||||
_eden_used = eden_list_length * HeapRegion::GrainBytes;
|
||||
_survivor_used = survivor_list_length * HeapRegion::GrainBytes;
|
||||
_young_region_num = young_list_length;
|
||||
_old_used = subtract_up_to_zero(_overall_used, _eden_used + _survivor_used);
|
||||
|
||||
// First calculate the committed sizes that can be calculated independently.
|
||||
_survivor_committed = _survivor_used;
|
||||
_old_committed = HeapRegion::align_up_to_region_byte_size(_old_used);
|
||||
|
||||
// Next, start with the overall committed size.
|
||||
_overall_committed = g1->capacity();
|
||||
size_t committed = _overall_committed;
|
||||
|
||||
// Remove the committed size we have calculated so far (for the
|
||||
// survivor and old space).
|
||||
assert(committed >= (_survivor_committed + _old_committed), "sanity");
|
||||
committed -= _survivor_committed + _old_committed;
|
||||
|
||||
// Next, calculate and remove the committed size for the eden.
|
||||
_eden_committed = eden_list_max_length * HeapRegion::GrainBytes;
|
||||
// Somewhat defensive: be robust in case there are inaccuracies in
|
||||
// the calculations
|
||||
_eden_committed = MIN2(_eden_committed, committed);
|
||||
committed -= _eden_committed;
|
||||
|
||||
// Finally, give the rest to the old space...
|
||||
_old_committed += committed;
|
||||
// ..and calculate the young gen committed.
|
||||
_young_gen_committed = _eden_committed + _survivor_committed;
|
||||
|
||||
assert(_overall_committed ==
|
||||
(_eden_committed + _survivor_committed + _old_committed),
|
||||
"the committed sizes should add up");
|
||||
// Somewhat defensive: cap the eden used size to make sure it
|
||||
// never exceeds the committed size.
|
||||
_eden_used = MIN2(_eden_used, _eden_committed);
|
||||
// _survivor_committed and _old_committed are calculated in terms of
|
||||
// the corresponding _*_used value, so the next two conditions
|
||||
// should hold.
|
||||
assert(_survivor_used <= _survivor_committed, "post-condition");
|
||||
assert(_old_used <= _old_committed, "post-condition");
|
||||
}
|
||||
|
||||
size_t G1MonitoringSupport::overall_used() {
|
||||
return g1h()->used_unlocked();
|
||||
void G1MonitoringSupport::recalculate_eden_size() {
|
||||
G1CollectedHeap* g1 = g1h();
|
||||
|
||||
// When a new eden region is allocated, only the eden_used size is
|
||||
// affected (since we have recalculated everything else at the last GC).
|
||||
|
||||
size_t young_region_num = g1h()->young_list()->length();
|
||||
if (young_region_num > _young_region_num) {
|
||||
size_t diff = young_region_num - _young_region_num;
|
||||
_eden_used += diff * HeapRegion::GrainBytes;
|
||||
// Somewhat defensive: cap the eden used size to make sure it
|
||||
// never exceeds the committed size.
|
||||
_eden_used = MIN2(_eden_used, _eden_committed);
|
||||
_young_region_num = young_region_num;
|
||||
}
|
||||
}
|
||||
|
||||
size_t G1MonitoringSupport::eden_space_committed() {
|
||||
return MAX2(eden_space_used(), (size_t) HeapRegion::GrainBytes);
|
||||
}
|
||||
|
||||
size_t G1MonitoringSupport::eden_space_used() {
|
||||
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();
|
||||
eden_used = subtract_up_to_zero(eden_used, survivor_used);
|
||||
return eden_used;
|
||||
}
|
||||
|
||||
size_t G1MonitoringSupport::survivor_space_committed() {
|
||||
return MAX2(survivor_space_used(),
|
||||
(size_t) HeapRegion::GrainBytes);
|
||||
}
|
||||
|
||||
size_t G1MonitoringSupport::survivor_space_used() {
|
||||
size_t survivor_num = g1h()->g1_policy()->recorded_survivor_regions();
|
||||
size_t survivor_used = survivor_num * HeapRegion::GrainBytes;
|
||||
return survivor_used;
|
||||
}
|
||||
|
||||
size_t G1MonitoringSupport::old_space_committed() {
|
||||
size_t committed = overall_committed();
|
||||
size_t eden_committed = eden_space_committed();
|
||||
size_t survivor_committed = survivor_space_committed();
|
||||
committed = subtract_up_to_zero(committed, eden_committed);
|
||||
committed = subtract_up_to_zero(committed, survivor_committed);
|
||||
committed = MAX2(committed, (size_t) HeapRegion::GrainBytes);
|
||||
return committed;
|
||||
}
|
||||
|
||||
// See the comment near the top of g1MonitoringSupport.hpp for
|
||||
// an explanation of these calculations for "used" and "capacity".
|
||||
size_t G1MonitoringSupport::old_space_used() {
|
||||
size_t used = overall_used();
|
||||
size_t eden_used = eden_space_used();
|
||||
size_t survivor_used = survivor_space_used();
|
||||
used = subtract_up_to_zero(used, eden_used);
|
||||
used = subtract_up_to_zero(used, survivor_used);
|
||||
return used;
|
||||
}
|
||||
|
||||
void G1MonitoringSupport::update_counters() {
|
||||
void G1MonitoringSupport::update_sizes() {
|
||||
recalculate_sizes();
|
||||
if (UsePerfData) {
|
||||
eden_counters()->update_capacity(eden_space_committed());
|
||||
eden_counters()->update_capacity(pad_capacity(eden_space_committed()));
|
||||
eden_counters()->update_used(eden_space_used());
|
||||
to_counters()->update_capacity(survivor_space_committed());
|
||||
// only the to survivor space (s1) is active, so we don't need to
|
||||
// update the counteres for the from survivor space (s0)
|
||||
to_counters()->update_capacity(pad_capacity(survivor_space_committed()));
|
||||
to_counters()->update_used(survivor_space_used());
|
||||
old_space_counters()->update_capacity(old_space_committed());
|
||||
old_space_counters()->update_capacity(pad_capacity(old_space_committed()));
|
||||
old_space_counters()->update_used(old_space_used());
|
||||
non_young_collection_counters()->update_all();
|
||||
old_collection_counters()->update_all();
|
||||
young_collection_counters()->update_all();
|
||||
}
|
||||
}
|
||||
|
||||
void G1MonitoringSupport::update_eden_counters() {
|
||||
void G1MonitoringSupport::update_eden_size() {
|
||||
recalculate_eden_size();
|
||||
if (UsePerfData) {
|
||||
eden_counters()->update_capacity(eden_space_committed());
|
||||
eden_counters()->update_used(eden_space_used());
|
||||
}
|
||||
}
|
||||
|
@ -28,101 +28,93 @@
|
||||
#include "gc_implementation/shared/hSpaceCounters.hpp"
|
||||
|
||||
class G1CollectedHeap;
|
||||
class G1SpaceMonitoringSupport;
|
||||
|
||||
// Class for monitoring logical spaces in G1.
|
||||
// G1 defines a set of regions as a young
|
||||
// collection (analogous to a young generation).
|
||||
// The young collection is a logical generation
|
||||
// with no fixed chunk (see space.hpp) reflecting
|
||||
// the address space for the generation. In addition
|
||||
// to the young collection there is its complement
|
||||
// the non-young collection that is simply the regions
|
||||
// not in the young collection. The non-young collection
|
||||
// is treated here as a logical old generation only
|
||||
// because the monitoring tools expect a generational
|
||||
// heap. The monitoring tools expect that a Space
|
||||
// (see space.hpp) exists that describe the
|
||||
// address space of young collection and non-young
|
||||
// collection and such a view is provided here.
|
||||
// Class for monitoring logical spaces in G1. It provides data for
|
||||
// both G1's jstat counters as well as G1's memory pools.
|
||||
//
|
||||
// This class provides interfaces to access
|
||||
// the value of variables for the young collection
|
||||
// that include the "capacity" and "used" of the
|
||||
// young collection along with constant values
|
||||
// for the minimum and maximum capacities for
|
||||
// the logical spaces. Similarly for the non-young
|
||||
// collection.
|
||||
// G1 splits the heap into heap regions and each heap region belongs
|
||||
// to one of the following categories:
|
||||
//
|
||||
// Also provided are counters for G1 concurrent collections
|
||||
// and stop-the-world full heap collecitons.
|
||||
// * eden : regions that have been allocated since the last GC
|
||||
// * survivors : regions with objects that survived the last few GCs
|
||||
// * old : long-lived non-humongous regions
|
||||
// * humongous : humongous regions
|
||||
// * free : free regions
|
||||
//
|
||||
// Below is a description of how "used" and "capactiy"
|
||||
// (or committed) is calculated for the logical spaces.
|
||||
// The combination of eden and survivor regions form the equivalent of
|
||||
// the young generation in the other GCs. The combination of old and
|
||||
// humongous regions form the equivalent of the old generation in the
|
||||
// other GCs. Free regions do not have a good equivalent in the other
|
||||
// GCs given that they can be allocated as any of the other region types.
|
||||
//
|
||||
// 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:
|
||||
// The monitoring tools expect the heap to contain a number of
|
||||
// generations (young, old, perm) and each generation to contain a
|
||||
// number of spaces (young: eden, survivors, old). Given that G1 does
|
||||
// not maintain those spaces physically (e.g., the set of
|
||||
// non-contiguous eden regions can be considered as a "logical"
|
||||
// space), we'll provide the illusion that those generations and
|
||||
// spaces exist. In reality, each generation and space refers to a set
|
||||
// of heap regions that are potentially non-contiguous.
|
||||
//
|
||||
// survivor_used = survivor_num * region_size
|
||||
// eden_used = young_region_num * region_size - survivor_used
|
||||
// old_gen_used = overall_used - eden_used - survivor_used
|
||||
// This class provides interfaces to access the min, current, and max
|
||||
// capacity and current occupancy for each of G1's logical spaces and
|
||||
// generations we expose to the monitoring tools. Also provided are
|
||||
// counters for G1 concurrent collections and stop-the-world full heap
|
||||
// collections.
|
||||
//
|
||||
// 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.
|
||||
// Below is a description of how the various sizes are calculated.
|
||||
//
|
||||
// 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:
|
||||
// * Current Capacity
|
||||
//
|
||||
// old_gen_committed = overall_committed - eden_committed - survivor_committed
|
||||
// - heap_capacity = current heap capacity (e.g., current committed size)
|
||||
// - young_gen_capacity = current max young gen target capacity
|
||||
// (i.e., young gen target capacity + max allowed expansion capacity)
|
||||
// - survivor_capacity = current survivor region capacity
|
||||
// - eden_capacity = young_gen_capacity - survivor_capacity
|
||||
// - old_capacity = heap_capacity - young_gen_capacity
|
||||
//
|
||||
// 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.
|
||||
// What we do in the above is to distribute the free regions among
|
||||
// eden_capacity and old_capacity.
|
||||
//
|
||||
// 3) Another decision that is again not straightforward is what is
|
||||
// the max size that each memory pool can grow to. One way to do this
|
||||
// would be to use the committed size for the max for the eden and
|
||||
// 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):
|
||||
// * Occupancy
|
||||
//
|
||||
// old_gen_max = overall_max - eden_max - survivor_max
|
||||
// - young_gen_used = current young region capacity
|
||||
// - survivor_used = survivor_capacity
|
||||
// - eden_used = young_gen_used - survivor_used
|
||||
// - old_used = overall_used - young_gen_used
|
||||
//
|
||||
// Unfortunately, the above makes the max of each pool fluctuate over
|
||||
// time and, even though this is allowed according to the spec, it
|
||||
// broke several assumptions in the M&M framework (there were cases
|
||||
// where used would reach a value greater than max). So, for max we
|
||||
// use -1, which means "undefined" according to the spec.
|
||||
// Unfortunately, we currently only keep track of the number of
|
||||
// currently allocated young and survivor regions + the overall used
|
||||
// bytes in the heap, so the above can be a little inaccurate.
|
||||
//
|
||||
// 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.
|
||||
// * Min Capacity
|
||||
//
|
||||
// We set this to 0 for all spaces. We could consider setting the old
|
||||
// min capacity to the min capacity of the heap (see 7078465).
|
||||
//
|
||||
// * Max Capacity
|
||||
//
|
||||
// For jstat, we set the max capacity of all spaces to heap_capacity,
|
||||
// given that we don't always have a reasonably upper bound on how big
|
||||
// each space can grow. For the memory pools, we actually make the max
|
||||
// capacity undefined. We could consider setting the old max capacity
|
||||
// to the max capacity of the heap (see 7078465).
|
||||
//
|
||||
// If we had more accurate occupancy / capacity information per
|
||||
// region set the above calculations would be greatly simplified and
|
||||
// be made more accurate.
|
||||
//
|
||||
// We update all the above synchronously and we store the results in
|
||||
// fields so that we just read said fields when needed. A subtle point
|
||||
// is that all the above sizes need to be recalculated when the old
|
||||
// gen changes capacity (after a GC or after a humongous allocation)
|
||||
// but only the eden occupancy changes when a new eden region is
|
||||
// allocated. So, in the latter case we have minimal recalcuation to
|
||||
// do which is important as we want to keep the eden region allocation
|
||||
// path as low-overhead as possible.
|
||||
|
||||
class G1MonitoringSupport : public CHeapObj {
|
||||
G1CollectedHeap* _g1h;
|
||||
VirtualSpace* _g1_storage_addr;
|
||||
|
||||
// jstat performance counters
|
||||
// incremental collections both fully and partially young
|
||||
@ -133,9 +125,9 @@ class G1MonitoringSupport : public CHeapObj {
|
||||
// _from_counters, and _to_counters are associated with
|
||||
// this "generational" counter.
|
||||
GenerationCounters* _young_collection_counters;
|
||||
// non-young collection set counters. The _old_space_counters
|
||||
// old collection set counters. The _old_space_counters
|
||||
// below are associated with this "generational" counter.
|
||||
GenerationCounters* _non_young_collection_counters;
|
||||
GenerationCounters* _old_collection_counters;
|
||||
// Counters for the capacity and used for
|
||||
// the whole heap
|
||||
HSpaceCounters* _old_space_counters;
|
||||
@ -145,6 +137,27 @@ class G1MonitoringSupport : public CHeapObj {
|
||||
HSpaceCounters* _from_counters;
|
||||
HSpaceCounters* _to_counters;
|
||||
|
||||
// When it's appropriate to recalculate the various sizes (at the
|
||||
// end of a GC, when a new eden region is allocated, etc.) we store
|
||||
// them here so that we can easily report them when needed and not
|
||||
// have to recalculate them every time.
|
||||
|
||||
size_t _overall_reserved;
|
||||
size_t _overall_committed;
|
||||
size_t _overall_used;
|
||||
|
||||
size_t _young_region_num;
|
||||
size_t _young_gen_committed;
|
||||
size_t _eden_committed;
|
||||
size_t _eden_used;
|
||||
size_t _survivor_committed;
|
||||
size_t _survivor_used;
|
||||
|
||||
size_t _old_committed;
|
||||
size_t _old_used;
|
||||
|
||||
G1CollectedHeap* g1h() { return _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
|
||||
@ -160,15 +173,35 @@ class G1MonitoringSupport : public CHeapObj {
|
||||
}
|
||||
}
|
||||
|
||||
// Recalculate all the sizes.
|
||||
void recalculate_sizes();
|
||||
// Recalculate only what's necessary when a new eden region is allocated.
|
||||
void recalculate_eden_size();
|
||||
|
||||
public:
|
||||
G1MonitoringSupport(G1CollectedHeap* g1h, VirtualSpace* g1_storage_addr);
|
||||
G1MonitoringSupport(G1CollectedHeap* g1h);
|
||||
|
||||
G1CollectedHeap* g1h() { return _g1h; }
|
||||
VirtualSpace* g1_storage_addr() { return _g1_storage_addr; }
|
||||
// Unfortunately, the jstat tool assumes that no space has 0
|
||||
// capacity. In our case, given that each space is logical, it's
|
||||
// possible that no regions will be allocated to it, hence to have 0
|
||||
// capacity (e.g., if there are no survivor regions, the survivor
|
||||
// space has 0 capacity). The way we deal with this is to always pad
|
||||
// each capacity value we report to jstat by a very small amount to
|
||||
// make sure that it's never zero. Given that we sometimes have to
|
||||
// report a capacity of a generation that contains several spaces
|
||||
// (e.g., young gen includes one eden, two survivor spaces), the
|
||||
// mult parameter is provided in order to adding the appropriate
|
||||
// padding multiple times so that the capacities add up correctly.
|
||||
static size_t pad_capacity(size_t size_bytes, size_t mult = 1) {
|
||||
return size_bytes + MinObjAlignmentInBytes * mult;
|
||||
}
|
||||
|
||||
// Performance Counter accessors
|
||||
void update_counters();
|
||||
void update_eden_counters();
|
||||
// Recalculate all the sizes from scratch and update all the jstat
|
||||
// counters accordingly.
|
||||
void update_sizes();
|
||||
// Recalculate only what's necessary when a new eden region is
|
||||
// allocated and update any jstat counters that need to be updated.
|
||||
void update_eden_size();
|
||||
|
||||
CollectorCounters* incremental_collection_counters() {
|
||||
return _incremental_collection_counters;
|
||||
@ -176,8 +209,11 @@ class G1MonitoringSupport : public CHeapObj {
|
||||
CollectorCounters* full_collection_counters() {
|
||||
return _full_collection_counters;
|
||||
}
|
||||
GenerationCounters* non_young_collection_counters() {
|
||||
return _non_young_collection_counters;
|
||||
GenerationCounters* young_collection_counters() {
|
||||
return _young_collection_counters;
|
||||
}
|
||||
GenerationCounters* old_collection_counters() {
|
||||
return _old_collection_counters;
|
||||
}
|
||||
HSpaceCounters* old_space_counters() { return _old_space_counters; }
|
||||
HSpaceCounters* eden_counters() { return _eden_counters; }
|
||||
@ -187,17 +223,45 @@ class G1MonitoringSupport : public CHeapObj {
|
||||
// Monitoring support used by
|
||||
// MemoryService
|
||||
// jstat counters
|
||||
size_t overall_committed();
|
||||
size_t overall_used();
|
||||
|
||||
size_t eden_space_committed();
|
||||
size_t eden_space_used();
|
||||
size_t overall_reserved() { return _overall_reserved; }
|
||||
size_t overall_committed() { return _overall_committed; }
|
||||
size_t overall_used() { return _overall_used; }
|
||||
|
||||
size_t survivor_space_committed();
|
||||
size_t survivor_space_used();
|
||||
size_t young_gen_committed() { return _young_gen_committed; }
|
||||
size_t young_gen_max() { return overall_reserved(); }
|
||||
size_t eden_space_committed() { return _eden_committed; }
|
||||
size_t eden_space_used() { return _eden_used; }
|
||||
size_t survivor_space_committed() { return _survivor_committed; }
|
||||
size_t survivor_space_used() { return _survivor_used; }
|
||||
|
||||
size_t old_space_committed();
|
||||
size_t old_space_used();
|
||||
size_t old_gen_committed() { return old_space_committed(); }
|
||||
size_t old_gen_max() { return overall_reserved(); }
|
||||
size_t old_space_committed() { return _old_committed; }
|
||||
size_t old_space_used() { return _old_used; }
|
||||
};
|
||||
|
||||
class G1GenerationCounters: public GenerationCounters {
|
||||
protected:
|
||||
G1MonitoringSupport* _g1mm;
|
||||
|
||||
public:
|
||||
G1GenerationCounters(G1MonitoringSupport* g1mm,
|
||||
const char* name, int ordinal, int spaces,
|
||||
size_t min_capacity, size_t max_capacity,
|
||||
size_t curr_capacity);
|
||||
};
|
||||
|
||||
class G1YoungGenerationCounters: public G1GenerationCounters {
|
||||
public:
|
||||
G1YoungGenerationCounters(G1MonitoringSupport* g1mm, const char* name);
|
||||
virtual void update_all();
|
||||
};
|
||||
|
||||
class G1OldGenerationCounters: public G1GenerationCounters {
|
||||
public:
|
||||
G1OldGenerationCounters(G1MonitoringSupport* g1mm, const char* name);
|
||||
virtual void update_all();
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1MONITORINGSUPPORT_HPP
|
||||
|
@ -357,6 +357,11 @@ class HeapRegion: public G1OffsetTableContigSpace {
|
||||
static int GrainWords;
|
||||
static int CardsPerRegion;
|
||||
|
||||
static size_t align_up_to_region_byte_size(size_t sz) {
|
||||
return (sz + (size_t) GrainBytes - 1) &
|
||||
~((1 << (size_t) LogOfHRGrainBytes) - 1);
|
||||
}
|
||||
|
||||
// It sets up the heap region size (GrainBytes / GrainWords), as
|
||||
// well as other related fields that are based on the heap region
|
||||
// size (LogOfHRGrainBytes / LogOfHRGrainWords /
|
||||
|
@ -26,14 +26,10 @@
|
||||
#include "gc_implementation/shared/generationCounters.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
|
||||
|
||||
GenerationCounters::GenerationCounters(const char* name,
|
||||
int ordinal, int spaces,
|
||||
VirtualSpace* v):
|
||||
_virtual_space(v) {
|
||||
|
||||
void GenerationCounters::initialize(const char* name, int ordinal, int spaces,
|
||||
size_t min_capacity, size_t max_capacity,
|
||||
size_t curr_capacity) {
|
||||
if (UsePerfData) {
|
||||
|
||||
EXCEPTION_MARK;
|
||||
ResourceMark rm;
|
||||
|
||||
@ -51,18 +47,37 @@ GenerationCounters::GenerationCounters(const char* name,
|
||||
|
||||
cname = PerfDataManager::counter_name(_name_space, "minCapacity");
|
||||
PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes,
|
||||
_virtual_space == NULL ? 0 :
|
||||
_virtual_space->committed_size(), CHECK);
|
||||
min_capacity, CHECK);
|
||||
|
||||
cname = PerfDataManager::counter_name(_name_space, "maxCapacity");
|
||||
PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes,
|
||||
_virtual_space == NULL ? 0 :
|
||||
_virtual_space->reserved_size(), CHECK);
|
||||
max_capacity, CHECK);
|
||||
|
||||
cname = PerfDataManager::counter_name(_name_space, "capacity");
|
||||
_current_size = PerfDataManager::create_variable(SUN_GC, cname,
|
||||
PerfData::U_Bytes,
|
||||
_virtual_space == NULL ? 0 :
|
||||
_virtual_space->committed_size(), CHECK);
|
||||
_current_size =
|
||||
PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes,
|
||||
curr_capacity, CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
GenerationCounters::GenerationCounters(const char* name,
|
||||
int ordinal, int spaces,
|
||||
VirtualSpace* v)
|
||||
: _virtual_space(v) {
|
||||
assert(v != NULL, "don't call this constructor if v == NULL");
|
||||
initialize(name, ordinal, spaces,
|
||||
v->committed_size(), v->reserved_size(), v->committed_size());
|
||||
}
|
||||
|
||||
GenerationCounters::GenerationCounters(const char* name,
|
||||
int ordinal, int spaces,
|
||||
size_t min_capacity, size_t max_capacity,
|
||||
size_t curr_capacity)
|
||||
: _virtual_space(NULL) {
|
||||
initialize(name, ordinal, spaces, min_capacity, max_capacity, curr_capacity);
|
||||
}
|
||||
|
||||
void GenerationCounters::update_all() {
|
||||
assert(_virtual_space != NULL, "otherwise, override this method");
|
||||
_current_size->set_value(_virtual_space->committed_size());
|
||||
}
|
||||
|
@ -34,6 +34,11 @@
|
||||
class GenerationCounters: public CHeapObj {
|
||||
friend class VMStructs;
|
||||
|
||||
private:
|
||||
void initialize(const char* name, int ordinal, int spaces,
|
||||
size_t min_capacity, size_t max_capacity,
|
||||
size_t curr_capacity);
|
||||
|
||||
protected:
|
||||
PerfVariable* _current_size;
|
||||
VirtualSpace* _virtual_space;
|
||||
@ -48,11 +53,18 @@ class GenerationCounters: public CHeapObj {
|
||||
char* _name_space;
|
||||
|
||||
// This constructor is only meant for use with the PSGenerationCounters
|
||||
// constructor. The need for such an constructor should be eliminated
|
||||
// constructor. The need for such an constructor should be eliminated
|
||||
// when VirtualSpace and PSVirtualSpace are unified.
|
||||
GenerationCounters() : _name_space(NULL), _current_size(NULL), _virtual_space(NULL) {}
|
||||
public:
|
||||
GenerationCounters()
|
||||
: _name_space(NULL), _current_size(NULL), _virtual_space(NULL) {}
|
||||
|
||||
// This constructor is used for subclasses that do not have a space
|
||||
// associated with them (e.g, in G1).
|
||||
GenerationCounters(const char* name, int ordinal, int spaces,
|
||||
size_t min_capacity, size_t max_capacity,
|
||||
size_t curr_capacity);
|
||||
|
||||
public:
|
||||
GenerationCounters(const char* name, int ordinal, int spaces,
|
||||
VirtualSpace* v);
|
||||
|
||||
@ -60,10 +72,7 @@ class GenerationCounters: public CHeapObj {
|
||||
if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
|
||||
}
|
||||
|
||||
virtual void update_all() {
|
||||
_current_size->set_value(_virtual_space == NULL ? 0 :
|
||||
_virtual_space->committed_size());
|
||||
}
|
||||
virtual void update_all();
|
||||
|
||||
const char* name_space() const { return _name_space; }
|
||||
|
||||
|
@ -32,56 +32,28 @@
|
||||
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,
|
||||
undefined_max(),
|
||||
support_usage_threshold) {
|
||||
_g1mm(g1h->g1mm()), 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 MAX2(eden_space_used(g1h), (size_t) HeapRegion::GrainBytes);
|
||||
}
|
||||
|
||||
// See the comment at the top of g1MemoryPool.hpp
|
||||
size_t G1MemoryPoolSuper::eden_space_used(G1CollectedHeap* g1h) {
|
||||
return g1h->g1mm()->eden_space_used();
|
||||
}
|
||||
|
||||
// See the comment at the top of g1MemoryPool.hpp
|
||||
size_t G1MemoryPoolSuper::survivor_space_committed(G1CollectedHeap* g1h) {
|
||||
return g1h->g1mm()->survivor_space_committed();
|
||||
}
|
||||
|
||||
// See the comment at the top of g1MemoryPool.hpp
|
||||
size_t G1MemoryPoolSuper::survivor_space_used(G1CollectedHeap* g1h) {
|
||||
return g1h->g1mm()->survivor_space_used();
|
||||
}
|
||||
|
||||
// See the comment at the top of g1MemoryPool.hpp
|
||||
size_t G1MemoryPoolSuper::old_space_committed(G1CollectedHeap* g1h) {
|
||||
return g1h->g1mm()->old_space_committed();
|
||||
}
|
||||
|
||||
// See the comment at the top of g1MemoryPool.hpp
|
||||
size_t G1MemoryPoolSuper::old_space_used(G1CollectedHeap* g1h) {
|
||||
return g1h->g1mm()->old_space_used();
|
||||
}
|
||||
|
||||
G1EdenPool::G1EdenPool(G1CollectedHeap* g1h) :
|
||||
G1MemoryPoolSuper(g1h,
|
||||
"G1 Eden Space",
|
||||
eden_space_committed(g1h), /* init_size */
|
||||
g1h->g1mm()->eden_space_committed(), /* init_size */
|
||||
_undefined_max,
|
||||
false /* support_usage_threshold */) { }
|
||||
|
||||
MemoryUsage G1EdenPool::get_memory_usage() {
|
||||
size_t initial_sz = initial_size();
|
||||
size_t max_sz = max_size();
|
||||
size_t used = used_in_bytes();
|
||||
size_t committed = eden_space_committed(_g1h);
|
||||
size_t committed = _g1mm->eden_space_committed();
|
||||
|
||||
return MemoryUsage(initial_sz, used, committed, max_sz);
|
||||
}
|
||||
@ -89,14 +61,15 @@ MemoryUsage G1EdenPool::get_memory_usage() {
|
||||
G1SurvivorPool::G1SurvivorPool(G1CollectedHeap* g1h) :
|
||||
G1MemoryPoolSuper(g1h,
|
||||
"G1 Survivor Space",
|
||||
survivor_space_committed(g1h), /* init_size */
|
||||
g1h->g1mm()->survivor_space_committed(), /* init_size */
|
||||
_undefined_max,
|
||||
false /* support_usage_threshold */) { }
|
||||
|
||||
MemoryUsage G1SurvivorPool::get_memory_usage() {
|
||||
size_t initial_sz = initial_size();
|
||||
size_t max_sz = max_size();
|
||||
size_t used = used_in_bytes();
|
||||
size_t committed = survivor_space_committed(_g1h);
|
||||
size_t committed = _g1mm->survivor_space_committed();
|
||||
|
||||
return MemoryUsage(initial_sz, used, committed, max_sz);
|
||||
}
|
||||
@ -104,14 +77,15 @@ MemoryUsage G1SurvivorPool::get_memory_usage() {
|
||||
G1OldGenPool::G1OldGenPool(G1CollectedHeap* g1h) :
|
||||
G1MemoryPoolSuper(g1h,
|
||||
"G1 Old Gen",
|
||||
old_space_committed(g1h), /* init_size */
|
||||
g1h->g1mm()->old_space_committed(), /* init_size */
|
||||
_undefined_max,
|
||||
true /* support_usage_threshold */) { }
|
||||
|
||||
MemoryUsage G1OldGenPool::get_memory_usage() {
|
||||
size_t initial_sz = initial_size();
|
||||
size_t max_sz = max_size();
|
||||
size_t used = used_in_bytes();
|
||||
size_t committed = old_space_committed(_g1h);
|
||||
size_t committed = _g1mm->old_space_committed();
|
||||
|
||||
return MemoryUsage(initial_sz, used, committed, max_sz);
|
||||
}
|
||||
|
@ -26,12 +26,11 @@
|
||||
#define SHARE_VM_SERVICES_G1MEMORYPOOL_HPP
|
||||
|
||||
#ifndef SERIALGC
|
||||
#include "gc_implementation/g1/g1MonitoringSupport.hpp"
|
||||
#include "services/memoryPool.hpp"
|
||||
#include "services/memoryUsage.hpp"
|
||||
#endif
|
||||
|
||||
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
|
||||
@ -50,37 +49,19 @@ class G1CollectedHeap;
|
||||
// on this model.
|
||||
//
|
||||
|
||||
|
||||
// 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.
|
||||
// (G1EdenPool, G1SurvivorPool, G1OldGenPool).
|
||||
class G1MemoryPoolSuper : public CollectedMemoryPool {
|
||||
protected:
|
||||
G1CollectedHeap* _g1h;
|
||||
const static size_t _undefined_max = (size_t) -1;
|
||||
G1MonitoringSupport* _g1mm;
|
||||
|
||||
// Would only be called from subclasses.
|
||||
G1MemoryPoolSuper(G1CollectedHeap* g1h,
|
||||
const char* name,
|
||||
size_t init_size,
|
||||
size_t max_size,
|
||||
bool support_usage_threshold);
|
||||
|
||||
// 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 undefined_max() {
|
||||
return (size_t) -1;
|
||||
}
|
||||
|
||||
static size_t eden_space_committed(G1CollectedHeap* g1h);
|
||||
static size_t eden_space_used(G1CollectedHeap* g1h);
|
||||
|
||||
static size_t survivor_space_committed(G1CollectedHeap* g1h);
|
||||
static size_t survivor_space_used(G1CollectedHeap* g1h);
|
||||
|
||||
static size_t old_space_committed(G1CollectedHeap* g1h);
|
||||
static size_t old_space_used(G1CollectedHeap* g1h);
|
||||
};
|
||||
|
||||
// Memory pool that represents the G1 eden.
|
||||
@ -89,10 +70,10 @@ public:
|
||||
G1EdenPool(G1CollectedHeap* g1h);
|
||||
|
||||
size_t used_in_bytes() {
|
||||
return eden_space_used(_g1h);
|
||||
return _g1mm->eden_space_used();
|
||||
}
|
||||
size_t max_size() const {
|
||||
return undefined_max();
|
||||
return _undefined_max;
|
||||
}
|
||||
MemoryUsage get_memory_usage();
|
||||
};
|
||||
@ -103,10 +84,10 @@ public:
|
||||
G1SurvivorPool(G1CollectedHeap* g1h);
|
||||
|
||||
size_t used_in_bytes() {
|
||||
return survivor_space_used(_g1h);
|
||||
return _g1mm->survivor_space_used();
|
||||
}
|
||||
size_t max_size() const {
|
||||
return undefined_max();
|
||||
return _undefined_max;
|
||||
}
|
||||
MemoryUsage get_memory_usage();
|
||||
};
|
||||
@ -117,10 +98,10 @@ public:
|
||||
G1OldGenPool(G1CollectedHeap* g1h);
|
||||
|
||||
size_t used_in_bytes() {
|
||||
return old_space_used(_g1h);
|
||||
return _g1mm->old_space_used();
|
||||
}
|
||||
size_t max_size() const {
|
||||
return undefined_max();
|
||||
return _undefined_max;
|
||||
}
|
||||
MemoryUsage get_memory_usage();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user