提交 681cbb5e 编写于 作者: J johnc

6818524: G1: use ergonomic resizing of PLABs

Summary: Employ PLABStats instances to record information about survivor and old PLABs, and use the recorded stats to adjust the sizes of survivor and old PLABS.
Reviewed-by: johnc, ysr
Contributed-by: NBrandon Mitchell <brandon@twitter.com>
上级 89388ac6
...@@ -1891,6 +1891,8 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) : ...@@ -1891,6 +1891,8 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) :
_young_list(new YoungList(this)), _young_list(new YoungList(this)),
_gc_time_stamp(0), _gc_time_stamp(0),
_retained_old_gc_alloc_region(NULL), _retained_old_gc_alloc_region(NULL),
_survivor_plab_stats(YoungPLABSize, PLABWeight),
_old_plab_stats(OldPLABSize, PLABWeight),
_expand_heap_after_alloc_failure(true), _expand_heap_after_alloc_failure(true),
_surviving_young_words(NULL), _surviving_young_words(NULL),
_old_marking_cycles_started(0), _old_marking_cycles_started(0),
...@@ -4099,17 +4101,22 @@ size_t G1CollectedHeap::desired_plab_sz(GCAllocPurpose purpose) ...@@ -4099,17 +4101,22 @@ size_t G1CollectedHeap::desired_plab_sz(GCAllocPurpose purpose)
size_t gclab_word_size; size_t gclab_word_size;
switch (purpose) { switch (purpose) {
case GCAllocForSurvived: case GCAllocForSurvived:
gclab_word_size = YoungPLABSize; gclab_word_size = _survivor_plab_stats.desired_plab_sz();
break; break;
case GCAllocForTenured: case GCAllocForTenured:
gclab_word_size = OldPLABSize; gclab_word_size = _old_plab_stats.desired_plab_sz();
break; break;
default: default:
assert(false, "unknown GCAllocPurpose"); assert(false, "unknown GCAllocPurpose");
gclab_word_size = OldPLABSize; gclab_word_size = _old_plab_stats.desired_plab_sz();
break; break;
} }
return gclab_word_size;
// Prevent humongous PLAB sizes for two reasons:
// * PLABs are allocated using a similar paths as oops, but should
// never be in a humongous region
// * Allowing humongous PLABs needlessly churns the region free lists
return MIN2(_humongous_object_threshold_in_words, gclab_word_size);
} }
void G1CollectedHeap::init_mutator_alloc_region() { void G1CollectedHeap::init_mutator_alloc_region() {
...@@ -4165,6 +4172,11 @@ void G1CollectedHeap::release_gc_alloc_regions() { ...@@ -4165,6 +4172,11 @@ void G1CollectedHeap::release_gc_alloc_regions() {
// want either way so no reason to check explicitly for either // want either way so no reason to check explicitly for either
// condition. // condition.
_retained_old_gc_alloc_region = _old_gc_alloc_region.release(); _retained_old_gc_alloc_region = _old_gc_alloc_region.release();
if (ResizePLAB) {
_survivor_plab_stats.adjust_desired_plab_sz();
_old_plab_stats.adjust_desired_plab_sz();
}
} }
void G1CollectedHeap::abandon_gc_alloc_regions() { void G1CollectedHeap::abandon_gc_alloc_regions() {
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include "gc_implementation/g1/heapRegionSeq.hpp" #include "gc_implementation/g1/heapRegionSeq.hpp"
#include "gc_implementation/g1/heapRegionSets.hpp" #include "gc_implementation/g1/heapRegionSets.hpp"
#include "gc_implementation/shared/hSpaceCounters.hpp" #include "gc_implementation/shared/hSpaceCounters.hpp"
#include "gc_implementation/parNew/parGCAllocBuffer.hpp" #include "gc_implementation/shared/parGCAllocBuffer.hpp"
#include "memory/barrierSet.hpp" #include "memory/barrierSet.hpp"
#include "memory/memRegion.hpp" #include "memory/memRegion.hpp"
#include "memory/sharedHeap.hpp" #include "memory/sharedHeap.hpp"
...@@ -278,10 +278,33 @@ private: ...@@ -278,10 +278,33 @@ private:
// survivor objects. // survivor objects.
SurvivorGCAllocRegion _survivor_gc_alloc_region; SurvivorGCAllocRegion _survivor_gc_alloc_region;
// PLAB sizing policy for survivors.
PLABStats _survivor_plab_stats;
// Alloc region used to satisfy allocation requests by the GC for // Alloc region used to satisfy allocation requests by the GC for
// old objects. // old objects.
OldGCAllocRegion _old_gc_alloc_region; OldGCAllocRegion _old_gc_alloc_region;
// PLAB sizing policy for tenured objects.
PLABStats _old_plab_stats;
PLABStats* stats_for_purpose(GCAllocPurpose purpose) {
PLABStats* stats = NULL;
switch (purpose) {
case GCAllocForSurvived:
stats = &_survivor_plab_stats;
break;
case GCAllocForTenured:
stats = &_old_plab_stats;
break;
default:
assert(false, "unrecognized GCAllocPurpose");
}
return stats;
}
// The last old region we allocated to during the last GC. // The last old region we allocated to during the last GC.
// Typically, it is not full so we should re-use it during the next GC. // Typically, it is not full so we should re-use it during the next GC.
HeapRegion* _retained_old_gc_alloc_region; HeapRegion* _retained_old_gc_alloc_region;
...@@ -314,7 +337,7 @@ private: ...@@ -314,7 +337,7 @@ private:
G1MonitoringSupport* _g1mm; G1MonitoringSupport* _g1mm;
// Determines PLAB size for a particular allocation purpose. // Determines PLAB size for a particular allocation purpose.
static size_t desired_plab_sz(GCAllocPurpose purpose); size_t desired_plab_sz(GCAllocPurpose purpose);
// Outside of GC pauses, the number of bytes used in all regions other // Outside of GC pauses, the number of bytes used in all regions other
// than the current allocation region. // than the current allocation region.
...@@ -1811,19 +1834,19 @@ public: ...@@ -1811,19 +1834,19 @@ public:
} }
HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz) { HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz) {
HeapWord* obj = NULL; HeapWord* obj = NULL;
size_t gclab_word_size = _g1h->desired_plab_sz(purpose); size_t gclab_word_size = _g1h->desired_plab_sz(purpose);
if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) { if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose); G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose);
assert(gclab_word_size == alloc_buf->word_sz(),
"dynamic resizing is not supported");
add_to_alloc_buffer_waste(alloc_buf->words_remaining()); add_to_alloc_buffer_waste(alloc_buf->words_remaining());
alloc_buf->retire(false, false); alloc_buf->flush_stats_and_retire(_g1h->stats_for_purpose(purpose),
false /* end_of_gc */,
false /* retain */);
HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size); HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size);
if (buf == NULL) return NULL; // Let caller handle allocation failure. if (buf == NULL) return NULL; // Let caller handle allocation failure.
// Otherwise. // Otherwise.
alloc_buf->set_word_size(gclab_word_size);
alloc_buf->set_buf(buf); alloc_buf->set_buf(buf);
obj = alloc_buf->allocate(word_sz); obj = alloc_buf->allocate(word_sz);
...@@ -1908,7 +1931,9 @@ public: ...@@ -1908,7 +1931,9 @@ public:
for (int ap = 0; ap < GCAllocPurposeCount; ++ap) { for (int ap = 0; ap < GCAllocPurposeCount; ++ap) {
size_t waste = _alloc_buffers[ap]->words_remaining(); size_t waste = _alloc_buffers[ap]->words_remaining();
add_to_alloc_buffer_waste(waste); add_to_alloc_buffer_waste(waste);
_alloc_buffers[ap]->retire(true, false); _alloc_buffers[ap]->flush_stats_and_retire(_g1h->stats_for_purpose((GCAllocPurpose)ap),
true /* end_of_gc */,
false /* retain */);
} }
} }
......
...@@ -24,11 +24,11 @@ ...@@ -24,11 +24,11 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp" #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp"
#include "gc_implementation/parNew/parGCAllocBuffer.hpp"
#include "gc_implementation/parNew/parNewGeneration.hpp" #include "gc_implementation/parNew/parNewGeneration.hpp"
#include "gc_implementation/parNew/parOopClosures.inline.hpp" #include "gc_implementation/parNew/parOopClosures.inline.hpp"
#include "gc_implementation/shared/adaptiveSizePolicy.hpp" #include "gc_implementation/shared/adaptiveSizePolicy.hpp"
#include "gc_implementation/shared/ageTable.hpp" #include "gc_implementation/shared/ageTable.hpp"
#include "gc_implementation/shared/parGCAllocBuffer.hpp"
#include "gc_implementation/shared/spaceDecorator.hpp" #include "gc_implementation/shared/spaceDecorator.hpp"
#include "memory/defNewGeneration.inline.hpp" #include "memory/defNewGeneration.inline.hpp"
#include "memory/genCollectedHeap.hpp" #include "memory/genCollectedHeap.hpp"
...@@ -453,7 +453,8 @@ void ParScanThreadStateSet::flush() ...@@ -453,7 +453,8 @@ void ParScanThreadStateSet::flush()
// retire the last buffer. // retire the last buffer.
par_scan_state.to_space_alloc_buffer()-> par_scan_state.to_space_alloc_buffer()->
flush_stats_and_retire(_gen.plab_stats(), flush_stats_and_retire(_gen.plab_stats(),
false /* !retain */); true /* end_of_gc */,
false /* retain */);
// Every thread has its own age table. We need to merge // Every thread has its own age table. We need to merge
// them all into one. // them all into one.
......
/* /*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP #ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP
#define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP #define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP
#include "gc_implementation/parNew/parGCAllocBuffer.hpp" #include "gc_implementation/shared/parGCAllocBuffer.hpp"
#include "memory/defNewGeneration.hpp" #include "memory/defNewGeneration.hpp"
#include "utilities/taskqueue.hpp" #include "utilities/taskqueue.hpp"
......
/* /*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
*/ */
#include "precompiled.hpp" #include "precompiled.hpp"
#include "gc_implementation/parNew/parGCAllocBuffer.hpp" #include "gc_implementation/shared/parGCAllocBuffer.hpp"
#include "memory/sharedHeap.hpp" #include "memory/sharedHeap.hpp"
#include "oops/arrayOop.hpp" #include "oops/arrayOop.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
...@@ -110,9 +110,7 @@ void PLABStats::adjust_desired_plab_sz() { ...@@ -110,9 +110,7 @@ void PLABStats::adjust_desired_plab_sz() {
plab_sz = align_object_size(plab_sz); plab_sz = align_object_size(plab_sz);
// Latch the result // Latch the result
if (PrintPLAB) gclog_or_tty->print(" desired_plab_sz = %d) ", plab_sz); if (PrintPLAB) gclog_or_tty->print(" desired_plab_sz = %d) ", plab_sz);
if (ResizePLAB) { _desired_plab_sz = plab_sz;
_desired_plab_sz = plab_sz;
}
// Now clear the accumulators for next round: // Now clear the accumulators for next round:
// note this needs to be fixed in the case where we // note this needs to be fixed in the case where we
// are retaining across scavenges. FIX ME !!! XXX // are retaining across scavenges. FIX ME !!! XXX
......
/* /*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -121,14 +121,14 @@ public: ...@@ -121,14 +121,14 @@ public:
// Flush the stats supporting ergonomic sizing of PLAB's // Flush the stats supporting ergonomic sizing of PLAB's
void flush_stats(PLABStats* stats); void flush_stats(PLABStats* stats);
void flush_stats_and_retire(PLABStats* stats, bool retain) { void flush_stats_and_retire(PLABStats* stats, bool end_of_gc, bool retain) {
// We flush the stats first in order to get a reading of // We flush the stats first in order to get a reading of
// unused space in the last buffer. // unused space in the last buffer.
if (ResizePLAB) { if (ResizePLAB) {
flush_stats(stats); flush_stats(stats);
} }
// Retire the last allocation buffer. // Retire the last allocation buffer.
retire(true, retain); retire(end_of_gc, retain);
} }
// Force future allocations to fail and queries for contains() // Force future allocations to fail and queries for contains()
......
/* /*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
*/ */
#include "precompiled.hpp" #include "precompiled.hpp"
#include "gc_implementation/parNew/parGCAllocBuffer.hpp"
#include "gc_implementation/shared/collectorCounters.hpp" #include "gc_implementation/shared/collectorCounters.hpp"
#include "gc_implementation/shared/parGCAllocBuffer.hpp"
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "memory/blockOffsetTable.inline.hpp" #include "memory/blockOffsetTable.inline.hpp"
#include "memory/generation.inline.hpp" #include "memory/generation.inline.hpp"
......
/* /*
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -306,7 +306,6 @@ ...@@ -306,7 +306,6 @@
# include "gc_implementation/g1/g1_specialized_oop_closures.hpp" # include "gc_implementation/g1/g1_specialized_oop_closures.hpp"
# include "gc_implementation/g1/ptrQueue.hpp" # include "gc_implementation/g1/ptrQueue.hpp"
# include "gc_implementation/g1/satbQueue.hpp" # include "gc_implementation/g1/satbQueue.hpp"
# include "gc_implementation/parNew/parGCAllocBuffer.hpp"
# include "gc_implementation/parNew/parOopClosures.hpp" # include "gc_implementation/parNew/parOopClosures.hpp"
# include "gc_implementation/parallelScavenge/objectStartArray.hpp" # include "gc_implementation/parallelScavenge/objectStartArray.hpp"
# include "gc_implementation/parallelScavenge/parMarkBitMap.hpp" # include "gc_implementation/parallelScavenge/parMarkBitMap.hpp"
...@@ -322,6 +321,7 @@ ...@@ -322,6 +321,7 @@
# include "gc_implementation/parallelScavenge/psYoungGen.hpp" # include "gc_implementation/parallelScavenge/psYoungGen.hpp"
# include "gc_implementation/shared/gcAdaptivePolicyCounters.hpp" # include "gc_implementation/shared/gcAdaptivePolicyCounters.hpp"
# include "gc_implementation/shared/gcPolicyCounters.hpp" # include "gc_implementation/shared/gcPolicyCounters.hpp"
# include "gc_implementation/shared/parGCAllocBuffer.hpp"
#endif // SERIALGC #endif // SERIALGC
#endif // !DONT_USE_PRECOMPILED_HEADER #endif // !DONT_USE_PRECOMPILED_HEADER
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册