diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp index 66e7bca9ce6..2066a949507 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp @@ -92,12 +92,17 @@ void ShenandoahHeuristics::choose_collection_set(ShenandoahCollectionSet* collec size_t free = 0; size_t free_regions = 0; + size_t total_live = 0; + ShenandoahMarkingContext* const ctx = heap->complete_marking_context(); for (size_t i = 0; i < num_regions; i++) { ShenandoahHeapRegion* region = heap->get_region(i); - size_t garbage = region->garbage(); + size_t live = region->get_live_data_bytes(); + size_t garbage = region->used() - live; + assert(region->garbage() == garbage, "Garbage calculation should agree"); + total_garbage += garbage; if (region->is_empty()) { @@ -114,9 +119,11 @@ void ShenandoahHeuristics::choose_collection_set(ShenandoahCollectionSet* collec candidates[cand_idx]._region = region; candidates[cand_idx]._garbage = garbage; cand_idx++; + + // This region has live data, add up to estimate. + total_live += live; } } else if (region->is_humongous_start()) { - // Reclaim humongous regions here, and count them as the immediate garbage #ifdef ASSERT bool reg_live = region->has_live(); bool bm_live = ctx->is_marked(oop(region->bottom())); @@ -124,7 +131,11 @@ void ShenandoahHeuristics::choose_collection_set(ShenandoahCollectionSet* collec "Humongous liveness and marks should agree. Region live: %s; Bitmap live: %s; Region Live Words: " SIZE_FORMAT, BOOL_TO_STR(reg_live), BOOL_TO_STR(bm_live), region->get_live_data_words()); #endif - if (!region->has_live()) { + if (region->has_live()) { + // Humongous region is live, count the entire chain as live. + total_live += oop(region->bottom())->size() * HeapWordSize; + } else { + // Reclaim humongous regions here, and count them as the immediate garbage heap->trash_humongous_region_at(region); // Count only the start. Continuations would be counted on "trash" path @@ -141,6 +152,9 @@ void ShenandoahHeuristics::choose_collection_set(ShenandoahCollectionSet* collec // Step 2. Look back at garbage statistics, and decide if we want to collect anything, // given the amount of immediately reclaimable garbage. If we do, figure out the collection set. + // Update the live data estimate + heap->set_live(total_live); + assert (immediate_garbage <= total_garbage, "Cannot have more immediate garbage than total garbage: " SIZE_FORMAT "%s vs " SIZE_FORMAT "%s", byte_size_in_proper_unit(immediate_garbage), proper_unit_for_byte_size(immediate_garbage), diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp index 33bfc1398c1..38c4adfad7d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp @@ -263,7 +263,6 @@ void ShenandoahConcurrentMark::finish_mark() { ShenandoahHeap* const heap = ShenandoahHeap::heap(); heap->set_concurrent_mark_in_progress(false); heap->mark_complete_marking_context(); - heap->update_live(); } void ShenandoahConcurrentMark::finish_mark_work() { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp index de1bab6fd0b..8d8e432efd1 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp @@ -1057,6 +1057,7 @@ void ShenandoahFullGC::phase4_compact_objects(ShenandoahHeapRegionSet** worker_s ShenandoahPostCompactClosure post_compact; heap->heap_region_iterate(&post_compact); heap->set_used(post_compact.get_live()); + heap->set_live(post_compact.get_live()); heap->collection_set()->clear(); heap->free_set()->rebuild(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp index 0fc9c61ac18..ec43ca102d6 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -574,7 +574,6 @@ public: inline ShenandoahMarkingContext* marking_context() const; inline void mark_complete_marking_context(); inline void mark_incomplete_marking_context(); - inline void update_live(); template inline void marked_object_iterate(ShenandoahHeapRegion* region, T* cl); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp index fb86d71510d..c39737c15b8 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp @@ -488,29 +488,6 @@ inline void ShenandoahHeap::mark_complete_marking_context() { _marking_context->mark_complete(); } -// a heap-region iterating closure to collect the liveness estimate -class ShenandoahCollectLiveSizeClosure : public ShenandoahHeapRegionClosure { - private: - size_t _live; - - public: - ShenandoahCollectLiveSizeClosure() : _live(0) {} - - void heap_region_do(ShenandoahHeapRegion* r) { - _live += r->get_live_data_bytes(); - } - - size_t get_live() { - return _live; - } -}; - -inline void ShenandoahHeap::update_live() { - ShenandoahCollectLiveSizeClosure cl; - heap_region_iterate(&cl); - set_live(cl.get_live()); -} - inline void ShenandoahHeap::mark_incomplete_marking_context() { _marking_context->mark_incomplete(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp b/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp index d1a46cf5c3d..dbdffd1417b 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp @@ -92,7 +92,6 @@ void ShenandoahSTWMark::mark() { } heap->mark_complete_marking_context(); - heap->update_live(); assert(task_queues()->is_empty(), "Should be empty"); TASKQUEUE_STATS_ONLY(task_queues()->print_taskqueue_stats());