Mercurial > hg > jdk9-shenandoah > hotspot
changeset 9445:98bc77f54ead
Adding a new Shenandoah heuristic called 'newadaptive'.
author | Raoul Veroy <rveroy@cs.tufts.edu> |
---|---|
date | Tue, 11 Aug 2015 17:02:16 -0400 |
parents | 4a1d26f20b62 |
children | ea0fa7eace6e |
files | src/share/vm/gc_implementation/shenandoah/shenandoahCollectorPolicy.cpp src/share/vm/gc_implementation/shenandoah/shenandoahCollectorPolicy.hpp src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp src/share/vm/gc_implementation/shenandoah/shenandoahHeap.hpp src/share/vm/runtime/globals.hpp |
diffstat | 5 files changed, 145 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/shenandoah/shenandoahCollectorPolicy.cpp Tue Aug 11 13:01:06 2015 +0200 +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahCollectorPolicy.cpp Tue Aug 11 17:02:16 2015 -0400 @@ -9,12 +9,18 @@ size_t _bytes_allocated_since_CM; size_t _bytes_reclaimed_this_cycle; +protected: + size_t _bytes_allocated_start_CM; + size_t _bytes_allocated_during_CM; + public: ShenandoahHeuristics(); void record_bytes_allocated(size_t bytes); void record_bytes_reclaimed(size_t bytes); + void record_bytes_start_CM(size_t bytes); + void record_bytes_end_CM(size_t bytes); virtual bool should_start_concurrent_mark(size_t used, size_t capacity) const=0; virtual bool update_refs_early(); @@ -26,7 +32,9 @@ ShenandoahHeuristics::ShenandoahHeuristics() : _bytes_allocated_since_CM(0), - _bytes_reclaimed_this_cycle(0) + _bytes_reclaimed_this_cycle(0), + _bytes_allocated_start_CM(0), + _bytes_allocated_during_CM(0) { if (PrintGCDetails) tty->print_cr("initializing heuristics"); @@ -81,15 +89,18 @@ // assert(heap->calculateUsed() == heap->used(), "Stashed heap used must be equal to calculated heap used"); gclog_or_tty->print_cr("]"); - if (phase == recycle_regions) + if (phase == recycle_regions) { _tracer->report_gc_end(_conc_timer->gc_end(), _conc_timer->time_partitions()); - else if (phase == full_gc) + } else if (phase == full_gc) { _tracer->report_gc_end(_stw_timer->gc_end(), _stw_timer->time_partitions()); - else if (phase == conc_mark || phase == conc_evac || phase == conc_uprefs || phase == prepare_evac) { + } else if (phase == conc_mark || phase == conc_evac || phase == conc_uprefs || phase == prepare_evac) { if (_conc_gc_aborted) { - _tracer->report_gc_end(_conc_timer->gc_end(), _conc_timer->time_partitions()); - clear_conc_gc_aborted(); + _tracer->report_gc_end(_conc_timer->gc_end(), _conc_timer->time_partitions()); + clear_conc_gc_aborted(); } + } else if (phase == final_evac) { + ShenandoahHeap* heap = ShenandoahHeap::heap(); + this->record_bytes_end_CM(heap->_bytesAllocSinceCM); } } } @@ -108,6 +119,7 @@ void ShenandoahHeuristics::record_bytes_allocated(size_t bytes) { _bytes_allocated_since_CM = bytes; + _bytes_allocated_start_CM = bytes; _allocation_rate_bytes.add(bytes); } @@ -116,6 +128,15 @@ _reclamation_rate_bytes.add(bytes); } +void ShenandoahHeuristics::record_bytes_start_CM(size_t bytes) { + _bytes_allocated_start_CM = bytes; +} + +void ShenandoahHeuristics::record_bytes_end_CM(size_t bytes) { + _bytes_allocated_during_CM = (bytes > _bytes_allocated_start_CM) ? (bytes - _bytes_allocated_start_CM) + : bytes; +} + class AggressiveHeuristics : public ShenandoahHeuristics { public: AggressiveHeuristics() : ShenandoahHeuristics(){ @@ -411,6 +432,87 @@ } }; +class NewAdaptiveHeuristics : public ShenandoahHeuristics { +private: + size_t _max_live_data; + double _target_heap_occupancy_factor; + double _allocation_threshold_factor; + size_t _last_bytesAllocSinceCM; + + uintx _target_heap_occupancy; + uintx _allocation_threshold; + +public: + NewAdaptiveHeuristics() : ShenandoahHeuristics() + { + if (PrintGCDetails) { + tty->print_cr("Initializing newadaptive heuristics"); + } + _max_live_data = 0; + _allocation_threshold = 0; + _target_heap_occupancy_factor = 0.; + _allocation_threshold_factor = 0.; + _last_bytesAllocSinceCM = 0; + } + + virtual ~NewAdaptiveHeuristics() {} + + virtual bool should_start_concurrent_mark(size_t used, size_t capacity) const + { + if (this->_bytes_allocated_during_CM > 0) { + // Not the first concurrent mark. + // _bytes_allocated_during_CM + ShenandoahHeap *heap = ShenandoahHeap::heap(); + size_t threshold_bytes_allocated = heap->capacity() / 4; + size_t targetStartMarking = (size_t) capacity * this->_target_heap_occupancy_factor; + return (used > targetStartMarking) && (this->_bytes_allocated_during_CM > threshold_bytes_allocated); + } else { + // First concurrent mark. + size_t targetStartMarking = capacity / 2; + ShenandoahHeap *heap = ShenandoahHeap::heap(); + size_t threshold_bytes_allocated = heap->capacity() / 4; + + // Need to check that an appropriate number of regions have + // been allocated since last concurrent mark too. + return (used > targetStartMarking) && (heap->_bytesAllocSinceCM > threshold_bytes_allocated); + } + } + + virtual void choose_collection_and_free_sets(ShenandoahHeapRegionSet* region_set, + ShenandoahHeapRegionSet* collection_set, + ShenandoahHeapRegionSet* free_set) + { + ShenandoahHeap *_heap = ShenandoahHeap::heap(); + this->_last_bytesAllocSinceCM = ShenandoahHeap::heap()->_bytesAllocSinceCM; + if (this->_last_bytesAllocSinceCM > 0) { + size_t min_garbage = this->_last_bytesAllocSinceCM; + region_set->choose_collection_and_free_sets_min_garbage(collection_set, free_set, min_garbage); + } else { + region_set->set_garbage_threshold(ShenandoahHeapRegion::RegionSizeBytes / 2); + region_set->choose_collection_and_free_sets(collection_set, free_set); + } + this->_max_live_data = MAX2(this->_max_live_data, collection_set->live_data()); + } + + void set_target_heap_occupancy(uintx target_heap_occupancy) { + this->_target_heap_occupancy_factor = get_percent(target_heap_occupancy); + this->_target_heap_occupancy = target_heap_occupancy; + } + + void set_allocation_threshold(uintx allocationThreshold) { + this->_allocation_threshold_factor = get_percent(allocationThreshold); + this->_allocation_threshold = allocationThreshold; + } + + uintx get_allocation_threshold() { + return this->_allocation_threshold; + } + + uintx get_target_heap_occupancy() { + return this->_target_heap_occupancy; + } +}; + static DynamicHeuristics *configureDynamicHeuristics() { DynamicHeuristics *heuristics = new DynamicHeuristics(); @@ -427,6 +529,19 @@ return heuristics; } + +static NewAdaptiveHeuristics* configureNewAdaptiveHeuristics() { + NewAdaptiveHeuristics* heuristics = new NewAdaptiveHeuristics(); + + heuristics->set_target_heap_occupancy(ShenandoahTargetHeapOccupancy); + if (ShenandoahLogConfig) { + tty->print_cr( "Shenandoah newadaptive heuristics target heap occupancy: "SIZE_FORMAT, + heuristics->get_target_heap_occupancy() ); + } + return heuristics; +} + + ShenandoahCollectorPolicy::ShenandoahCollectorPolicy() { ShenandoahHeapRegion::setup_heap_region_size(initial_heap_byte_size(), initial_heap_byte_size()); @@ -492,6 +607,11 @@ tty->print_cr("Shenandoah heuristics: adaptive"); } _heuristics = new AdaptiveHeuristics(); + } else if (strcmp(ShenandoahGCHeuristics, "newadaptive") == 0) { + if (ShenandoahLogConfig) { + tty->print_cr("Shenandoah heuristics: newadaptive"); + } + _heuristics = configureNewAdaptiveHeuristics(); } else { fatal("Unknown -XX:ShenandoahGCHeuristics option"); } @@ -542,6 +662,15 @@ void ShenandoahCollectorPolicy::record_bytes_allocated(size_t bytes) { _heuristics->record_bytes_allocated(bytes); } + +void ShenandoahCollectorPolicy::record_bytes_start_CM(size_t bytes) { + _heuristics->record_bytes_start_CM(bytes); +} + +void ShenandoahCollectorPolicy::record_bytes_end_CM(size_t bytes) { + _heuristics->record_bytes_end_CM(bytes); +} + void ShenandoahCollectorPolicy::record_bytes_reclaimed(size_t bytes) { _heuristics->record_bytes_reclaimed(bytes); }
--- a/src/share/vm/gc_implementation/shenandoah/shenandoahCollectorPolicy.hpp Tue Aug 11 13:01:06 2015 +0200 +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahCollectorPolicy.hpp Tue Aug 11 17:02:16 2015 -0400 @@ -93,6 +93,8 @@ void record_bytes_allocated(size_t bytes); void record_bytes_reclaimed(size_t bytes); + void record_bytes_start_CM(size_t bytes); + void record_bytes_end_CM(size_t bytes); bool should_start_concurrent_mark(size_t used, size_t capacity); void choose_collection_and_free_sets(ShenandoahHeapRegionSet* region_set, ShenandoahHeapRegionSet* collection_set,
--- a/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp Tue Aug 11 13:01:06 2015 +0200 +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp Tue Aug 11 17:02:16 2015 -0400 @@ -185,7 +185,7 @@ _free_regions(NULL), _collection_set(NULL), _bytesAllocSinceCM(0), - _bytes_allocated_since_last_cm(0), + _bytes_allocated_during_cm(0), _max_allocated_gc(0), _allocated_last_gc(0), _used_start_gc(0),
--- a/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.hpp Tue Aug 11 13:01:06 2015 +0200 +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.hpp Tue Aug 11 17:02:16 2015 -0400 @@ -114,7 +114,8 @@ public: size_t _bytesAllocSinceCM; - size_t _bytes_allocated_since_last_cm; + size_t _bytes_allocated_during_cm; + size_t _bytes_allocated_during_cm_start; size_t _max_allocated_gc; size_t _allocated_last_gc; size_t _used_start_gc;
--- a/src/share/vm/runtime/globals.hpp Tue Aug 11 13:01:06 2015 +0200 +++ b/src/share/vm/runtime/globals.hpp Tue Aug 11 17:02:16 2015 -0400 @@ -1647,6 +1647,11 @@ "phase. Applies to Shenandoah GC dynamic Heuristic mode only " \ "(ignored otherwise)") \ \ + product(uintx, ShenandoahTargetHeapOccupancy, 80, \ + "Sets the target maximum percentage occupance of the heap we" \ + "would like to maintain." \ + "Shenandoah GC newadaptive Heuristic mode only.") \ + \ product(bool, ShenandoahPrintCollectionSet, false, \ "Print the collection set before each GC phase") \ \