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) {
|