< prev index next >

src/share/vm/gc/shenandoah/shenandoahCollectorPolicy.cpp

Print this page
rev 13320 : Use peak occupancy to optimize/pessimize free_threshold in adaptive heuristics.


 129 
 130   virtual void record_cm_success() {
 131     _cancelled_cm_cycles_in_a_row = 0;
 132     _successful_cm_cycles_in_a_row++;
 133   }
 134 
 135   virtual void record_uprefs_cancelled() {
 136     _cancelled_uprefs_cycles_in_a_row++;
 137     _successful_uprefs_cycles_in_a_row = 0;
 138   }
 139 
 140   virtual void record_uprefs_success() {
 141     _cancelled_uprefs_cycles_in_a_row = 0;
 142     _successful_uprefs_cycles_in_a_row++;
 143   }
 144 
 145   virtual void record_full_gc() {
 146     _bytes_in_cset = 0;
 147   }
 148 



 149   virtual void start_choose_collection_set() {
 150   }
 151   virtual void end_choose_collection_set() {
 152   }
 153   virtual bool region_in_collection_set(ShenandoahHeapRegion* r, size_t immediate_garbage) = 0;
 154 
 155   virtual void choose_collection_set(ShenandoahCollectionSet* collection_set, int* connections=NULL);
 156   virtual void choose_free_set(ShenandoahFreeSet* free_set);
 157 
 158   virtual bool process_references() {
 159     if (ShenandoahRefProcFrequency == 0) return false;
 160     size_t cycle = ShenandoahHeap::heap()->shenandoahPolicy()->cycle_counter();
 161     // Process references every Nth GC cycle.
 162     return cycle % ShenandoahRefProcFrequency == 0;
 163   }
 164 
 165   virtual bool unload_classes() {
 166     if (ShenandoahUnloadClassesFrequency == 0) return false;
 167     size_t cycle = ShenandoahHeap::heap()->shenandoahPolicy()->cycle_counter();
 168     // Unload classes every Nth GC cycle.


 452       // Need to check that an appropriate number of regions have
 453       // been allocated since last concurrent mark too.
 454       shouldStartConcurrentMark = true;
 455     }
 456 
 457     return shouldStartConcurrentMark;
 458   }
 459 
 460   virtual bool region_in_collection_set(ShenandoahHeapRegion* r, size_t immediate_garbage) {
 461     size_t threshold = ShenandoahHeapRegion::region_size_bytes() * ShenandoahGarbageThreshold / 100;
 462     return r->garbage() > threshold;
 463   }
 464 
 465 };
 466 
 467 
 468 class AdaptiveHeuristics : public ShenandoahHeuristics {
 469 private:
 470   uintx _free_threshold;
 471   TruncatedSeq* _cset_history;
 472 
 473 public:
 474   AdaptiveHeuristics() :
 475     ShenandoahHeuristics(),
 476     _free_threshold(ShenandoahInitFreeThreshold),

 477     _cset_history(new TruncatedSeq((uint)ShenandoahHappyCyclesThreshold)) {
 478 
 479     _cset_history->add((double) ShenandoahCSetThreshold);
 480     _cset_history->add((double) ShenandoahCSetThreshold);
 481   }
 482 
 483   virtual ~AdaptiveHeuristics() {
 484     delete _cset_history;
 485   }
 486 
 487   virtual bool region_in_collection_set(ShenandoahHeapRegion* r, size_t immediate_garbage) {
 488     size_t threshold = ShenandoahHeapRegion::region_size_bytes() * ShenandoahGarbageThreshold / 100;
 489     return r->garbage() > threshold;
 490   }
 491 












 492   void optimize_free_threshold(uint successful_cycles) {
 493     if (successful_cycles > ShenandoahHappyCyclesThreshold &&
 494         _free_threshold > ShenandoahMinFreeThreshold) {
 495       _free_threshold--;
 496       log_info(gc,ergo)("reducing free threshold to: "UINTX_FORMAT, _free_threshold);
 497       _successful_cm_cycles_in_a_row = 0;
 498     }
 499   }
 500 
 501   void pessimize_free_threshold() {
 502     if (_free_threshold < ShenandoahMaxFreeThreshold) {
 503       _free_threshold++;
 504       log_info(gc,ergo)("increasing free threshold to: "UINTX_FORMAT, _free_threshold);
 505     }
 506   }
 507 
 508   virtual void record_cm_cancelled() {
 509     ShenandoahHeuristics::record_cm_cancelled();
 510     pessimize_free_threshold();
 511   }
 512 
 513   virtual void record_cm_success() {
 514     ShenandoahHeuristics::record_cm_success();
 515     if (! update_refs_early()) {
 516       optimize_free_threshold(_successful_cm_cycles_in_a_row);
 517     }
 518   }
 519 
 520   virtual void record_uprefs_cancelled() {
 521     ShenandoahHeuristics::record_uprefs_cancelled();
 522     pessimize_free_threshold();
 523   }
 524 
 525   virtual void record_uprefs_success() {
 526     ShenandoahHeuristics::record_uprefs_success();
 527     optimize_free_threshold(_successful_uprefs_cycles_in_a_row);
 528   }
 529 
 530   virtual void record_full_gc() {
 531     ShenandoahHeuristics::record_full_gc();
 532     pessimize_free_threshold();
 533   }
 534 



 535 
 536   virtual bool should_start_concurrent_mark(size_t used, size_t capacity) const {
 537     bool shouldStartConcurrentMark = false;
 538 
 539     ShenandoahHeap* heap = ShenandoahHeap::heap();
 540     size_t free_capacity = heap->free_regions()->capacity();
 541     size_t free_used = heap->free_regions()->used();
 542     assert(free_used <= free_capacity, "must use less than capacity");
 543     size_t available =  free_capacity - free_used;
 544     uintx factor = _free_threshold;
 545     size_t cset_threshold = 0;
 546     if (!update_refs_early()) {
 547       // Count in the memory available after cset reclamation.
 548       cset_threshold = (size_t) _cset_history->davg();
 549       size_t cset = MIN2(_bytes_in_cset, (cset_threshold * capacity) / 100);
 550       available += cset;
 551       factor += cset_threshold;
 552     }
 553 
 554     size_t targetStartMarking = (capacity * factor) / 100;


1013 
1014 void ShenandoahCollectorPolicy::record_cm_cancelled() {
1015   _heuristics->record_cm_cancelled();
1016 }
1017 
1018 void ShenandoahCollectorPolicy::record_uprefs_success() {
1019   _heuristics->record_uprefs_success();
1020   _successful_uprefs++;
1021 }
1022 
1023 void ShenandoahCollectorPolicy::record_uprefs_degenerated() {
1024   _degenerated_uprefs++;
1025 }
1026 
1027 void ShenandoahCollectorPolicy::record_uprefs_cancelled() {
1028   _heuristics->record_uprefs_cancelled();
1029 }
1030 
1031 void ShenandoahCollectorPolicy::record_full_gc() {
1032   _heuristics->record_full_gc();




1033 }
1034 
1035 void ShenandoahCollectorPolicy::choose_collection_set(ShenandoahCollectionSet* collection_set, int* connections) {
1036   _heuristics->choose_collection_set(collection_set, connections);
1037 }
1038 
1039 void ShenandoahCollectorPolicy::choose_free_set(ShenandoahFreeSet* free_set) {
1040    _heuristics->choose_free_set(free_set);
1041 }
1042 
1043 
1044 bool ShenandoahCollectorPolicy::process_references() {
1045   return _heuristics->process_references();
1046 }
1047 
1048 bool ShenandoahCollectorPolicy::unload_classes() {
1049   return _heuristics->unload_classes();
1050 }
1051 
1052 void ShenandoahCollectorPolicy::print_tracing_info(outputStream* out) {




 129 
 130   virtual void record_cm_success() {
 131     _cancelled_cm_cycles_in_a_row = 0;
 132     _successful_cm_cycles_in_a_row++;
 133   }
 134 
 135   virtual void record_uprefs_cancelled() {
 136     _cancelled_uprefs_cycles_in_a_row++;
 137     _successful_uprefs_cycles_in_a_row = 0;
 138   }
 139 
 140   virtual void record_uprefs_success() {
 141     _cancelled_uprefs_cycles_in_a_row = 0;
 142     _successful_uprefs_cycles_in_a_row++;
 143   }
 144 
 145   virtual void record_full_gc() {
 146     _bytes_in_cset = 0;
 147   }
 148 
 149   virtual void record_peak_occupancy() {
 150   }
 151 
 152   virtual void start_choose_collection_set() {
 153   }
 154   virtual void end_choose_collection_set() {
 155   }
 156   virtual bool region_in_collection_set(ShenandoahHeapRegion* r, size_t immediate_garbage) = 0;
 157 
 158   virtual void choose_collection_set(ShenandoahCollectionSet* collection_set, int* connections=NULL);
 159   virtual void choose_free_set(ShenandoahFreeSet* free_set);
 160 
 161   virtual bool process_references() {
 162     if (ShenandoahRefProcFrequency == 0) return false;
 163     size_t cycle = ShenandoahHeap::heap()->shenandoahPolicy()->cycle_counter();
 164     // Process references every Nth GC cycle.
 165     return cycle % ShenandoahRefProcFrequency == 0;
 166   }
 167 
 168   virtual bool unload_classes() {
 169     if (ShenandoahUnloadClassesFrequency == 0) return false;
 170     size_t cycle = ShenandoahHeap::heap()->shenandoahPolicy()->cycle_counter();
 171     // Unload classes every Nth GC cycle.


 455       // Need to check that an appropriate number of regions have
 456       // been allocated since last concurrent mark too.
 457       shouldStartConcurrentMark = true;
 458     }
 459 
 460     return shouldStartConcurrentMark;
 461   }
 462 
 463   virtual bool region_in_collection_set(ShenandoahHeapRegion* r, size_t immediate_garbage) {
 464     size_t threshold = ShenandoahHeapRegion::region_size_bytes() * ShenandoahGarbageThreshold / 100;
 465     return r->garbage() > threshold;
 466   }
 467 
 468 };
 469 
 470 
 471 class AdaptiveHeuristics : public ShenandoahHeuristics {
 472 private:
 473   uintx _free_threshold;
 474   TruncatedSeq* _cset_history;
 475   size_t _peak_occupancy;
 476 public:
 477   AdaptiveHeuristics() :
 478     ShenandoahHeuristics(),
 479     _free_threshold(ShenandoahInitFreeThreshold),
 480     _peak_occupancy(0),
 481     _cset_history(new TruncatedSeq((uint)ShenandoahHappyCyclesThreshold)) {
 482 
 483     _cset_history->add((double) ShenandoahCSetThreshold);
 484     _cset_history->add((double) ShenandoahCSetThreshold);
 485   }
 486 
 487   virtual ~AdaptiveHeuristics() {
 488     delete _cset_history;
 489   }
 490 
 491   virtual bool region_in_collection_set(ShenandoahHeapRegion* r, size_t immediate_garbage) {
 492     size_t threshold = ShenandoahHeapRegion::region_size_bytes() * ShenandoahGarbageThreshold / 100;
 493     return r->garbage() > threshold;
 494   }
 495 
 496   void handle_gc_success(uint successful_cycles) {
 497     ShenandoahHeap* heap = ShenandoahHeap::heap();
 498     size_t capacity = heap->capacity();
 499     size_t available = heap->capacity() - _peak_occupancy;
 500     if (available * 100 / capacity <= ShenandoahMinFreeThreshold) {
 501       pessimize_free_threshold();
 502     } else {
 503       optimize_free_threshold(successful_cycles);
 504     }
 505     _peak_occupancy = 0;
 506   }
 507 
 508   void optimize_free_threshold(uint successful_cycles) {
 509     if (successful_cycles > ShenandoahHappyCyclesThreshold &&
 510         _free_threshold > 0) {
 511       _free_threshold--;
 512       log_info(gc,ergo)("reducing free threshold to: "UINTX_FORMAT, _free_threshold);
 513       _successful_cm_cycles_in_a_row = 0;
 514     }
 515   }
 516 
 517   void pessimize_free_threshold() {
 518     if (_free_threshold < ShenandoahMaxFreeThreshold) {
 519       _free_threshold++;
 520       log_info(gc,ergo)("increasing free threshold to: "UINTX_FORMAT, _free_threshold);
 521     }
 522   }
 523 
 524   virtual void record_cm_cancelled() {
 525     ShenandoahHeuristics::record_cm_cancelled();
 526     pessimize_free_threshold();
 527   }
 528 
 529   virtual void record_cm_success() {
 530     ShenandoahHeuristics::record_cm_success();
 531     if (! update_refs_early()) {
 532       handle_gc_success(_successful_cm_cycles_in_a_row);
 533     }
 534   }
 535 
 536   virtual void record_uprefs_cancelled() {
 537     ShenandoahHeuristics::record_uprefs_cancelled();
 538     pessimize_free_threshold();
 539   }
 540 
 541   virtual void record_uprefs_success() {
 542     ShenandoahHeuristics::record_uprefs_success();
 543     handle_gc_success(_successful_uprefs_cycles_in_a_row);
 544   }
 545 
 546   virtual void record_full_gc() {
 547     ShenandoahHeuristics::record_full_gc();
 548     pessimize_free_threshold();
 549   }
 550 
 551   virtual void record_peak_occupancy() {
 552     _peak_occupancy = MAX2(_peak_occupancy, ShenandoahHeap::heap()->used());
 553   }
 554 
 555   virtual bool should_start_concurrent_mark(size_t used, size_t capacity) const {
 556     bool shouldStartConcurrentMark = false;
 557 
 558     ShenandoahHeap* heap = ShenandoahHeap::heap();
 559     size_t free_capacity = heap->free_regions()->capacity();
 560     size_t free_used = heap->free_regions()->used();
 561     assert(free_used <= free_capacity, "must use less than capacity");
 562     size_t available =  free_capacity - free_used;
 563     uintx factor = _free_threshold;
 564     size_t cset_threshold = 0;
 565     if (!update_refs_early()) {
 566       // Count in the memory available after cset reclamation.
 567       cset_threshold = (size_t) _cset_history->davg();
 568       size_t cset = MIN2(_bytes_in_cset, (cset_threshold * capacity) / 100);
 569       available += cset;
 570       factor += cset_threshold;
 571     }
 572 
 573     size_t targetStartMarking = (capacity * factor) / 100;


1032 
1033 void ShenandoahCollectorPolicy::record_cm_cancelled() {
1034   _heuristics->record_cm_cancelled();
1035 }
1036 
1037 void ShenandoahCollectorPolicy::record_uprefs_success() {
1038   _heuristics->record_uprefs_success();
1039   _successful_uprefs++;
1040 }
1041 
1042 void ShenandoahCollectorPolicy::record_uprefs_degenerated() {
1043   _degenerated_uprefs++;
1044 }
1045 
1046 void ShenandoahCollectorPolicy::record_uprefs_cancelled() {
1047   _heuristics->record_uprefs_cancelled();
1048 }
1049 
1050 void ShenandoahCollectorPolicy::record_full_gc() {
1051   _heuristics->record_full_gc();
1052 }
1053 
1054 void ShenandoahCollectorPolicy::record_peak_occupancy() {
1055   _heuristics->record_peak_occupancy();
1056 }
1057 
1058 void ShenandoahCollectorPolicy::choose_collection_set(ShenandoahCollectionSet* collection_set, int* connections) {
1059   _heuristics->choose_collection_set(collection_set, connections);
1060 }
1061 
1062 void ShenandoahCollectorPolicy::choose_free_set(ShenandoahFreeSet* free_set) {
1063    _heuristics->choose_free_set(free_set);
1064 }
1065 
1066 
1067 bool ShenandoahCollectorPolicy::process_references() {
1068   return _heuristics->process_references();
1069 }
1070 
1071 bool ShenandoahCollectorPolicy::unload_classes() {
1072   return _heuristics->unload_classes();
1073 }
1074 
1075 void ShenandoahCollectorPolicy::print_tracing_info(outputStream* out) {


< prev index next >