提交 c182ec48 编写于 作者: T tonyp

7113006: G1: excessive ergo output when an evac failure happens

Summary: Introduce a flag that is set when a heap expansion attempt during a GC fails so that we do not consantly attempt to expand the heap when it's going to fail anyway. This not only prevents the excessive ergo output (which is generated when a region allocation fails) but also avoids excessive and ultimately unsuccessful expansion attempts.
Reviewed-by: jmasa, johnc
上级 3107a5b1
...@@ -591,17 +591,29 @@ HeapRegion* G1CollectedHeap::new_region(size_t word_size, bool do_expand) { ...@@ -591,17 +591,29 @@ HeapRegion* G1CollectedHeap::new_region(size_t word_size, bool do_expand) {
} }
res = new_region_try_secondary_free_list(); res = new_region_try_secondary_free_list();
} }
if (res == NULL && do_expand) { if (res == NULL && do_expand && _expand_heap_after_alloc_failure) {
// Currently, only attempts to allocate GC alloc regions set
// do_expand to true. So, we should only reach here during a
// safepoint. If this assumption changes we might have to
// reconsider the use of _expand_heap_after_alloc_failure.
assert(SafepointSynchronize::is_at_safepoint(), "invariant");
ergo_verbose1(ErgoHeapSizing, ergo_verbose1(ErgoHeapSizing,
"attempt heap expansion", "attempt heap expansion",
ergo_format_reason("region allocation request failed") ergo_format_reason("region allocation request failed")
ergo_format_byte("allocation request"), ergo_format_byte("allocation request"),
word_size * HeapWordSize); word_size * HeapWordSize);
if (expand(word_size * HeapWordSize)) { if (expand(word_size * HeapWordSize)) {
// Even though the heap was expanded, it might not have reached // Given that expand() succeeded in expanding the heap, and we
// the desired size. So, we cannot assume that the allocation // always expand the heap by an amount aligned to the heap
// will succeed. // region size, the free list should in theory not be empty. So
// it would probably be OK to use remove_head(). But the extra
// check for NULL is unlikely to be a performance issue here (we
// just expanded the heap!) so let's just be conservative and
// use remove_head_or_null().
res = _free_list.remove_head_or_null(); res = _free_list.remove_head_or_null();
} else {
_expand_heap_after_alloc_failure = false;
} }
} }
return res; return res;
...@@ -1838,6 +1850,7 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) : ...@@ -1838,6 +1850,7 @@ 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),
_expand_heap_after_alloc_failure(true),
_surviving_young_words(NULL), _surviving_young_words(NULL),
_full_collections_completed(0), _full_collections_completed(0),
_in_cset_fast_test(NULL), _in_cset_fast_test(NULL),
...@@ -5439,6 +5452,7 @@ void G1CollectedHeap::enqueue_discovered_references() { ...@@ -5439,6 +5452,7 @@ void G1CollectedHeap::enqueue_discovered_references() {
} }
void G1CollectedHeap::evacuate_collection_set() { void G1CollectedHeap::evacuate_collection_set() {
_expand_heap_after_alloc_failure = true;
set_evacuation_failed(false); set_evacuation_failed(false);
g1_rem_set()->prepare_for_oops_into_collection_set_do(); g1_rem_set()->prepare_for_oops_into_collection_set_do();
......
...@@ -285,6 +285,14 @@ private: ...@@ -285,6 +285,14 @@ private:
// 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;
// It specifies whether we should attempt to expand the heap after a
// region allocation failure. If heap expansion fails we set this to
// false so that we don't re-attempt the heap expansion (it's likely
// that subsequent expansion attempts will also fail if one fails).
// Currently, it is only consulted during GC and it's reset at the
// start of each GC.
bool _expand_heap_after_alloc_failure;
// It resets the mutator alloc region before new allocations can take place. // It resets the mutator alloc region before new allocations can take place.
void init_mutator_alloc_region(); void init_mutator_alloc_region();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册