提交 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_) :
_young_list(new YoungList(this)),
_gc_time_stamp(0),
_retained_old_gc_alloc_region(NULL),
_survivor_plab_stats(YoungPLABSize, PLABWeight),
_old_plab_stats(OldPLABSize, PLABWeight),
_expand_heap_after_alloc_failure(true),
_surviving_young_words(NULL),
_old_marking_cycles_started(0),
......@@ -4099,17 +4101,22 @@ size_t G1CollectedHeap::desired_plab_sz(GCAllocPurpose purpose)
size_t gclab_word_size;
switch (purpose) {
case GCAllocForSurvived:
gclab_word_size = YoungPLABSize;
gclab_word_size = _survivor_plab_stats.desired_plab_sz();
break;
case GCAllocForTenured:
gclab_word_size = OldPLABSize;
gclab_word_size = _old_plab_stats.desired_plab_sz();
break;
default:
assert(false, "unknown GCAllocPurpose");
gclab_word_size = OldPLABSize;
gclab_word_size = _old_plab_stats.desired_plab_sz();
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() {
......@@ -4165,6 +4172,11 @@ void G1CollectedHeap::release_gc_alloc_regions() {
// want either way so no reason to check explicitly for either
// condition.
_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() {
......
......@@ -33,7 +33,7 @@
#include "gc_implementation/g1/heapRegionSeq.hpp"
#include "gc_implementation/g1/heapRegionSets.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/memRegion.hpp"
#include "memory/sharedHeap.hpp"
......@@ -278,10 +278,33 @@ private:
// survivor objects.
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
// old objects.
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.
// Typically, it is not full so we should re-use it during the next GC.
HeapRegion* _retained_old_gc_alloc_region;
......@@ -314,7 +337,7 @@ private:
G1MonitoringSupport* _g1mm;
// 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
// than the current allocation region.
......@@ -1811,19 +1834,19 @@ public:
}
HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz) {
HeapWord* obj = NULL;
size_t gclab_word_size = _g1h->desired_plab_sz(purpose);
if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
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());
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);
if (buf == NULL) return NULL; // Let caller handle allocation failure.
// Otherwise.
alloc_buf->set_word_size(gclab_word_size);
alloc_buf->set_buf(buf);
obj = alloc_buf->allocate(word_sz);
......@@ -1908,7 +1931,9 @@ public:
for (int ap = 0; ap < GCAllocPurposeCount; ++ap) {
size_t waste = _alloc_buffers[ap]->words_remaining();
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 @@
#include "precompiled.hpp"
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp"
#include "gc_implementation/parNew/parGCAllocBuffer.hpp"
#include "gc_implementation/parNew/parNewGeneration.hpp"
#include "gc_implementation/parNew/parOopClosures.inline.hpp"
#include "gc_implementation/shared/adaptiveSizePolicy.hpp"
#include "gc_implementation/shared/ageTable.hpp"
#include "gc_implementation/shared/parGCAllocBuffer.hpp"
#include "gc_implementation/shared/spaceDecorator.hpp"
#include "memory/defNewGeneration.inline.hpp"
#include "memory/genCollectedHeap.hpp"
......@@ -453,7 +453,8 @@ void ParScanThreadStateSet::flush()
// retire the last buffer.
par_scan_state.to_space_alloc_buffer()->
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
// 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,7 +25,7 @@
#ifndef 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 "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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -23,7 +23,7 @@
*/
#include "precompiled.hpp"
#include "gc_implementation/parNew/parGCAllocBuffer.hpp"
#include "gc_implementation/shared/parGCAllocBuffer.hpp"
#include "memory/sharedHeap.hpp"
#include "oops/arrayOop.hpp"
#include "oops/oop.inline.hpp"
......@@ -110,9 +110,7 @@ void PLABStats::adjust_desired_plab_sz() {
plab_sz = align_object_size(plab_sz);
// Latch the result
if (PrintPLAB) gclog_or_tty->print(" desired_plab_sz = %d) ", plab_sz);
if (ResizePLAB) {
_desired_plab_sz = plab_sz;
}
// Now clear the accumulators for next round:
// note this needs to be fixed in the case where we
// 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -121,14 +121,14 @@ public:
// Flush the stats supporting ergonomic sizing of PLAB's
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
// unused space in the last buffer.
if (ResizePLAB) {
flush_stats(stats);
}
// Retire the last allocation buffer.
retire(true, retain);
retire(end_of_gc, retain);
}
// 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -23,8 +23,8 @@
*/
#include "precompiled.hpp"
#include "gc_implementation/parNew/parGCAllocBuffer.hpp"
#include "gc_implementation/shared/collectorCounters.hpp"
#include "gc_implementation/shared/parGCAllocBuffer.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/blockOffsetTable.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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -306,7 +306,6 @@
# include "gc_implementation/g1/g1_specialized_oop_closures.hpp"
# include "gc_implementation/g1/ptrQueue.hpp"
# include "gc_implementation/g1/satbQueue.hpp"
# include "gc_implementation/parNew/parGCAllocBuffer.hpp"
# include "gc_implementation/parNew/parOopClosures.hpp"
# include "gc_implementation/parallelScavenge/objectStartArray.hpp"
# include "gc_implementation/parallelScavenge/parMarkBitMap.hpp"
......@@ -322,6 +321,7 @@
# include "gc_implementation/parallelScavenge/psYoungGen.hpp"
# include "gc_implementation/shared/gcAdaptivePolicyCounters.hpp"
# include "gc_implementation/shared/gcPolicyCounters.hpp"
# include "gc_implementation/shared/parGCAllocBuffer.hpp"
#endif // SERIALGC
#endif // !DONT_USE_PRECOMPILED_HEADER
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册