13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/parallel/parallelScavengeHeap.hpp"
27 #include "gc/parallel/psAdaptiveSizePolicy.hpp"
28 #include "gc/parallel/psGCAdaptivePolicyCounters.hpp"
29 #include "gc/parallel/psScavenge.hpp"
30 #include "gc/shared/collectorPolicy.hpp"
31 #include "gc/shared/gcCause.hpp"
32 #include "gc/shared/gcPolicyCounters.hpp"
33 #include "runtime/timer.hpp"
34 #include "utilities/top.hpp"
35
36 #include <math.h>
37
38 PSAdaptiveSizePolicy::PSAdaptiveSizePolicy(size_t init_eden_size,
39 size_t init_promo_size,
40 size_t init_survivor_size,
41 size_t space_alignment,
42 double gc_pause_goal_sec,
43 double gc_minor_pause_goal_sec,
44 uint gc_cost_ratio) :
45 AdaptiveSizePolicy(init_eden_size,
46 init_promo_size,
47 init_survivor_size,
48 gc_pause_goal_sec,
49 gc_cost_ratio),
50 _collection_cost_margin_fraction(AdaptiveSizePolicyCollectionCostMargin / 100.0),
51 _space_alignment(space_alignment),
52 _live_at_last_full_gc(init_promo_size),
142 if ((_latest_major_mutator_interval_seconds > 0.0) &&
143 (major_pause_in_seconds > 0.0)) {
144 double interval_in_seconds =
145 _latest_major_mutator_interval_seconds + major_pause_in_seconds;
146 collection_cost =
147 major_pause_in_seconds / interval_in_seconds;
148 avg_major_gc_cost()->sample(collection_cost);
149
150 // Sample for performance counter
151 _avg_major_interval->sample(interval_in_seconds);
152 }
153
154 // Calculate variables used to estimate pause time vs. gen sizes
155 double eden_size_in_mbytes = ((double)_eden_size)/((double)M);
156 double promo_size_in_mbytes = ((double)_promo_size)/((double)M);
157 _major_pause_old_estimator->update(promo_size_in_mbytes,
158 major_pause_in_ms);
159 _major_pause_young_estimator->update(eden_size_in_mbytes,
160 major_pause_in_ms);
161
162 if (PrintAdaptiveSizePolicy && Verbose) {
163 gclog_or_tty->print("psAdaptiveSizePolicy::major_collection_end: "
164 "major gc cost: %f average: %f", collection_cost,
165 avg_major_gc_cost()->average());
166 gclog_or_tty->print_cr(" major pause: %f major period %f",
167 major_pause_in_ms,
168 _latest_major_mutator_interval_seconds * MILLIUNITS);
169 }
170
171 // Calculate variable used to estimate collection cost vs. gen sizes
172 assert(collection_cost >= 0.0, "Expected to be non-negative");
173 _major_collection_estimator->update(promo_size_in_mbytes,
174 collection_cost);
175 }
176
177 // Update the amount live at the end of a full GC
178 _live_at_last_full_gc = amount_live;
179
180 // The policy does not have enough data until at least some major collections
181 // have been done.
182 if (_avg_major_pause->count() >= AdaptiveSizePolicyReadyThreshold) {
183 _old_gen_policy_is_ready = true;
184 }
185
186 // Interval times use this timer to measure the interval that
187 // the mutator runs. Reset after the GC pause has been measured.
188 _major_timer.reset();
189 _major_timer.start();
190 }
191
192 // If the remaining free space in the old generation is less that
193 // that expected to be needed by the next collection, do a full
194 // collection now.
195 bool PSAdaptiveSizePolicy::should_full_GC(size_t old_free_in_bytes) {
196
197 // A similar test is done in the scavenge's should_attempt_scavenge(). If
198 // this is changed, decide if that test should also be changed.
199 bool result = padded_average_promoted_in_bytes() > (float) old_free_in_bytes;
200 if (PrintGCDetails && Verbose) {
201 if (result) {
202 gclog_or_tty->print(" full after scavenge: ");
203 } else {
204 gclog_or_tty->print(" no full after scavenge: ");
205 }
206 gclog_or_tty->print_cr(" average_promoted " SIZE_FORMAT
207 " padded_average_promoted " SIZE_FORMAT
208 " free in old gen " SIZE_FORMAT,
209 (size_t) average_promoted_in_bytes(),
210 (size_t) padded_average_promoted_in_bytes(),
211 old_free_in_bytes);
212 }
213 return result;
214 }
215
216 void PSAdaptiveSizePolicy::clear_generation_free_space_flags() {
217
218 AdaptiveSizePolicy::clear_generation_free_space_flags();
219
220 set_change_old_gen_for_min_pauses(0);
221
222 set_change_young_gen_for_maj_pauses(0);
223 }
224
225 // If this is not a full GC, only test and modify the young generation.
226
227 void PSAdaptiveSizePolicy::compute_generations_free_space(
228 size_t young_live,
229 size_t eden_live,
230 size_t old_live,
231 size_t cur_eden,
232 size_t max_old_gen_size,
344 assert(minor_cost >= 0.0, "minor cost is < 0.0");
345 // Try to reduce the GC times.
346 adjust_eden_for_throughput(is_full_gc, &desired_eden_size);
347
348 } else {
349
350 // Be conservative about reducing the footprint.
351 // Do a minimum number of major collections first.
352 // Have reasonable averages for major and minor collections costs.
353 if (UseAdaptiveSizePolicyFootprintGoal &&
354 young_gen_policy_is_ready() &&
355 avg_major_gc_cost()->average() >= 0.0 &&
356 avg_minor_gc_cost()->average() >= 0.0) {
357 size_t desired_sum = desired_eden_size + desired_promo_size;
358 desired_eden_size = adjust_eden_for_footprint(desired_eden_size, desired_sum);
359 }
360 }
361
362 // Note we make the same tests as in the code block below; the code
363 // seems a little easier to read with the printing in another block.
364 if (PrintAdaptiveSizePolicy) {
365 if (desired_eden_size > eden_limit) {
366 gclog_or_tty->print_cr(
367 "PSAdaptiveSizePolicy::compute_eden_space_size limits:"
368 " desired_eden_size: " SIZE_FORMAT
369 " old_eden_size: " SIZE_FORMAT
370 " eden_limit: " SIZE_FORMAT
371 " cur_eden: " SIZE_FORMAT
372 " max_eden_size: " SIZE_FORMAT
373 " avg_young_live: " SIZE_FORMAT,
374 desired_eden_size, _eden_size, eden_limit, cur_eden,
375 max_eden_size, (size_t)avg_young_live()->average());
376 }
377 if (gc_cost() > gc_cost_limit) {
378 gclog_or_tty->print_cr(
379 "PSAdaptiveSizePolicy::compute_eden_space_size: gc time limit"
380 " gc_cost: %f "
381 " GCTimeLimit: " UINTX_FORMAT,
382 gc_cost(), GCTimeLimit);
383 }
384 }
385
386 // Align everything and make a final limit check
387 desired_eden_size = align_size_up(desired_eden_size, _space_alignment);
388 desired_eden_size = MAX2(desired_eden_size, _space_alignment);
389
390 eden_limit = align_size_down(eden_limit, _space_alignment);
391
392 // And one last limit check, now that we've aligned things.
393 if (desired_eden_size > eden_limit) {
394 // If the policy says to get a larger eden but
395 // is hitting the limit, don't decrease eden.
396 // This can lead to a general drifting down of the
397 // eden size. Let the tenuring calculation push more
398 // into the old gen.
399 desired_eden_size = MAX2(eden_limit, cur_eden);
400 }
401
402 if (PrintAdaptiveSizePolicy) {
403 // Timing stats
404 gclog_or_tty->print(
405 "PSAdaptiveSizePolicy::compute_eden_space_size: costs"
406 " minor_time: %f"
407 " major_cost: %f"
408 " mutator_cost: %f"
409 " throughput_goal: %f",
410 minor_gc_cost(), major_gc_cost(), mutator_cost(),
411 _throughput_goal);
412
413 // We give more details if Verbose is set
414 if (Verbose) {
415 gclog_or_tty->print( " minor_pause: %f"
416 " major_pause: %f"
417 " minor_interval: %f"
418 " major_interval: %f"
419 " pause_goal: %f",
420 _avg_minor_pause->padded_average(),
421 _avg_major_pause->padded_average(),
422 _avg_minor_interval->average(),
423 _avg_major_interval->average(),
424 gc_pause_goal_sec());
425 }
426
427 // Footprint stats
428 gclog_or_tty->print( " live_space: " SIZE_FORMAT
429 " free_space: " SIZE_FORMAT,
430 live_space(), free_space());
431 // More detail
432 if (Verbose) {
433 gclog_or_tty->print( " base_footprint: " SIZE_FORMAT
434 " avg_young_live: " SIZE_FORMAT
435 " avg_old_live: " SIZE_FORMAT,
436 (size_t)_avg_base_footprint->average(),
437 (size_t)avg_young_live()->average(),
438 (size_t)avg_old_live()->average());
439 }
440
441 // And finally, our old and new sizes.
442 gclog_or_tty->print(" old_eden_size: " SIZE_FORMAT
443 " desired_eden_size: " SIZE_FORMAT,
444 _eden_size, desired_eden_size);
445 gclog_or_tty->cr();
446 }
447
448 set_eden_size(desired_eden_size);
449 }
450
451 void PSAdaptiveSizePolicy::compute_old_gen_free_space(
452 size_t old_live,
453 size_t cur_eden,
454 size_t max_old_gen_size,
455 bool is_full_gc) {
456
457 // Update statistics
458 // Time statistics are updated as we go, update footprint stats here
459 if (is_full_gc) {
460 // old_live is only accurate after a full gc
461 avg_old_live()->sample(old_live);
462 }
463
464 // This code used to return if the policy was not ready , i.e.,
465 // policy_is_ready() returning false. The intent was that
466 // decisions below needed major collection times and so could
547 }
548 } else {
549
550 // Be conservative about reducing the footprint.
551 // Do a minimum number of major collections first.
552 // Have reasonable averages for major and minor collections costs.
553 if (UseAdaptiveSizePolicyFootprintGoal &&
554 young_gen_policy_is_ready() &&
555 avg_major_gc_cost()->average() >= 0.0 &&
556 avg_minor_gc_cost()->average() >= 0.0) {
557 if (is_full_gc) {
558 set_decide_at_full_gc(decide_at_full_gc_true);
559 size_t desired_sum = desired_eden_size + desired_promo_size;
560 desired_promo_size = adjust_promo_for_footprint(desired_promo_size, desired_sum);
561 }
562 }
563 }
564
565 // Note we make the same tests as in the code block below; the code
566 // seems a little easier to read with the printing in another block.
567 if (PrintAdaptiveSizePolicy) {
568 if (desired_promo_size > promo_limit) {
569 // "free_in_old_gen" was the original value for used for promo_limit
570 size_t free_in_old_gen = (size_t)(max_old_gen_size - avg_old_live()->average());
571 gclog_or_tty->print_cr(
572 "PSAdaptiveSizePolicy::compute_old_gen_free_space limits:"
573 " desired_promo_size: " SIZE_FORMAT
574 " promo_limit: " SIZE_FORMAT
575 " free_in_old_gen: " SIZE_FORMAT
576 " max_old_gen_size: " SIZE_FORMAT
577 " avg_old_live: " SIZE_FORMAT,
578 desired_promo_size, promo_limit, free_in_old_gen,
579 max_old_gen_size, (size_t) avg_old_live()->average());
580 }
581 if (gc_cost() > gc_cost_limit) {
582 gclog_or_tty->print_cr(
583 "PSAdaptiveSizePolicy::compute_old_gen_free_space: gc time limit"
584 " gc_cost: %f "
585 " GCTimeLimit: " UINTX_FORMAT,
586 gc_cost(), GCTimeLimit);
587 }
588 }
589
590 // Align everything and make a final limit check
591 desired_promo_size = align_size_up(desired_promo_size, _space_alignment);
592 desired_promo_size = MAX2(desired_promo_size, _space_alignment);
593
594 promo_limit = align_size_down(promo_limit, _space_alignment);
595
596 // And one last limit check, now that we've aligned things.
597 desired_promo_size = MIN2(desired_promo_size, promo_limit);
598
599 if (PrintAdaptiveSizePolicy) {
600 // Timing stats
601 gclog_or_tty->print(
602 "PSAdaptiveSizePolicy::compute_old_gen_free_space: costs"
603 " minor_time: %f"
604 " major_cost: %f"
605 " mutator_cost: %f"
606 " throughput_goal: %f",
607 minor_gc_cost(), major_gc_cost(), mutator_cost(),
608 _throughput_goal);
609
610 // We give more details if Verbose is set
611 if (Verbose) {
612 gclog_or_tty->print( " minor_pause: %f"
613 " major_pause: %f"
614 " minor_interval: %f"
615 " major_interval: %f"
616 " pause_goal: %f",
617 _avg_minor_pause->padded_average(),
618 _avg_major_pause->padded_average(),
619 _avg_minor_interval->average(),
620 _avg_major_interval->average(),
621 gc_pause_goal_sec());
622 }
623
624 // Footprint stats
625 gclog_or_tty->print( " live_space: " SIZE_FORMAT
626 " free_space: " SIZE_FORMAT,
627 live_space(), free_space());
628 // More detail
629 if (Verbose) {
630 gclog_or_tty->print( " base_footprint: " SIZE_FORMAT
631 " avg_young_live: " SIZE_FORMAT
632 " avg_old_live: " SIZE_FORMAT,
633 (size_t)_avg_base_footprint->average(),
634 (size_t)avg_young_live()->average(),
635 (size_t)avg_old_live()->average());
636 }
637
638 // And finally, our old and new sizes.
639 gclog_or_tty->print(" old_promo_size: " SIZE_FORMAT
640 " desired_promo_size: " SIZE_FORMAT,
641 _promo_size, desired_promo_size);
642 gclog_or_tty->cr();
643 }
644
645 set_promo_size(desired_promo_size);
646 }
647
648 void PSAdaptiveSizePolicy::decay_supplemental_growth(bool is_full_gc) {
649 // Decay the supplemental increment? Decay the supplement growth
650 // factor even if it is not used. It is only meant to give a boost
651 // to the initial growth and if it is not used, then it was not
652 // needed.
653 if (is_full_gc) {
654 // Don't wait for the threshold value for the major collections. If
655 // here, the supplemental growth term was used and should decay.
656 if ((_avg_major_pause->count() % TenuredGenerationSizeSupplementDecay)
657 == 0) {
658 _old_gen_size_increment_supplement =
659 _old_gen_size_increment_supplement >> 1;
660 }
661 } else {
662 if ((_avg_minor_pause->count() >= AdaptiveSizePolicyReadyThreshold) &&
663 (_avg_minor_pause->count() % YoungGenerationSizeSupplementDecay) == 0) {
702
703 if (_avg_minor_pause->padded_average() <= _avg_major_pause->padded_average() && is_full_gc) {
704 // Adjust for the major pause time only at full gc's because the
705 // affects of a change can only be seen at full gc's.
706
707 // Reduce old generation size to reduce pause?
708 if (major_pause_old_estimator()->decrement_will_decrease()) {
709 // reduce old generation size
710 set_change_old_gen_for_maj_pauses(decrease_old_gen_for_maj_pauses_true);
711 promo_heap_delta = promo_decrement_aligned_down(*desired_promo_size_ptr);
712 *desired_promo_size_ptr = _promo_size - promo_heap_delta;
713 } else {
714 // EXPERIMENTAL ADJUSTMENT
715 // Only record that the estimator indicated such an action.
716 // *desired_promo_size_ptr = _promo_size +
717 // promo_increment_aligned_up(*desired_promo_size_ptr);
718 set_change_old_gen_for_maj_pauses(increase_old_gen_for_maj_pauses_true);
719 }
720 }
721
722 if (PrintAdaptiveSizePolicy && Verbose) {
723 gclog_or_tty->print_cr(
724 "PSAdaptiveSizePolicy::adjust_promo_for_pause_time "
725 "adjusting gen sizes for major pause (avg %f goal %f). "
726 "desired_promo_size " SIZE_FORMAT " promo delta " SIZE_FORMAT,
727 _avg_major_pause->average(), gc_pause_goal_sec(),
728 *desired_promo_size_ptr, promo_heap_delta);
729 }
730 }
731
732 void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(bool is_full_gc,
733 size_t* desired_promo_size_ptr,
734 size_t* desired_eden_size_ptr) {
735
736 size_t eden_heap_delta = 0;
737 // Add some checks for a threshold for a change. For example,
738 // a change less than the required alignment is probably not worth
739 // attempting.
740 if (_avg_minor_pause->padded_average() > _avg_major_pause->padded_average()) {
741 adjust_eden_for_minor_pause_time(is_full_gc, desired_eden_size_ptr);
742 }
743 if (PrintAdaptiveSizePolicy && Verbose) {
744 gclog_or_tty->print_cr(
745 "PSAdaptiveSizePolicy::adjust_eden_for_pause_time "
746 "adjusting gen sizes for major pause (avg %f goal %f). "
747 "desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT,
748 _avg_major_pause->average(), gc_pause_goal_sec(),
749 *desired_eden_size_ptr, eden_heap_delta);
750 }
751 }
752
753 void PSAdaptiveSizePolicy::adjust_promo_for_throughput(bool is_full_gc,
754 size_t* desired_promo_size_ptr) {
755
756 // Add some checks for a threshold for a change. For example,
757 // a change less than the required alignment is probably not worth
758 // attempting.
759
760 if ((gc_cost() + mutator_cost()) == 0.0) {
761 return;
762 }
763
764 if (PrintAdaptiveSizePolicy && Verbose) {
765 gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_promo_for_throughput("
766 "is_full: %d, promo: " SIZE_FORMAT "): ",
767 is_full_gc, *desired_promo_size_ptr);
768 gclog_or_tty->print_cr("mutator_cost %f major_gc_cost %f "
769 "minor_gc_cost %f", mutator_cost(), major_gc_cost(), minor_gc_cost());
770 }
771
772 // Tenured generation
773 if (is_full_gc) {
774 // Calculate the change to use for the tenured gen.
775 size_t scaled_promo_heap_delta = 0;
776 // Can the increment to the generation be scaled?
777 if (gc_cost() >= 0.0 && major_gc_cost() >= 0.0) {
778 size_t promo_heap_delta =
779 promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr);
780 double scale_by_ratio = major_gc_cost() / gc_cost();
781 scaled_promo_heap_delta =
782 (size_t) (scale_by_ratio * (double) promo_heap_delta);
783 if (PrintAdaptiveSizePolicy && Verbose) {
784 gclog_or_tty->print_cr(
785 "Scaled tenured increment: " SIZE_FORMAT " by %f down to "
786 SIZE_FORMAT,
787 promo_heap_delta, scale_by_ratio, scaled_promo_heap_delta);
788 }
789 } else if (major_gc_cost() >= 0.0) {
790 // Scaling is not going to work. If the major gc time is the
791 // larger, give it a full increment.
792 if (major_gc_cost() >= minor_gc_cost()) {
793 scaled_promo_heap_delta =
794 promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr);
795 }
796 } else {
797 // Don't expect to get here but it's ok if it does
798 // in the product build since the delta will be 0
799 // and nothing will change.
800 assert(false, "Unexpected value for gc costs");
801 }
802
803 switch (AdaptiveSizeThroughPutPolicy) {
804 case 1:
805 // Early in the run the statistics might not be good. Until
806 // a specific number of collections have been, use the heuristic
807 // that a larger generation size means lower collection costs.
808 if (major_collection_estimator()->increment_will_decrease() ||
822 // the major collection cost but don't do it.
823 // *desired_promo_size_ptr = _promo_size -
824 // promo_decrement_aligned_down(*desired_promo_size_ptr);
825 set_change_old_gen_for_throughput(
826 decrease_old_gen_for_throughput_true);
827 }
828
829 break;
830 default:
831 // Simplest strategy
832 if ((*desired_promo_size_ptr + scaled_promo_heap_delta) >
833 *desired_promo_size_ptr) {
834 *desired_promo_size_ptr = *desired_promo_size_ptr +
835 scaled_promo_heap_delta;
836 }
837 set_change_old_gen_for_throughput(
838 increase_old_gen_for_throughput_true);
839 _old_gen_change_for_major_throughput++;
840 }
841
842 if (PrintAdaptiveSizePolicy && Verbose) {
843 gclog_or_tty->print_cr(
844 "adjusting tenured gen for throughput (avg %f goal %f). "
845 "desired_promo_size " SIZE_FORMAT " promo_delta " SIZE_FORMAT ,
846 mutator_cost(), _throughput_goal,
847 *desired_promo_size_ptr, scaled_promo_heap_delta);
848 }
849 }
850 }
851
852 void PSAdaptiveSizePolicy::adjust_eden_for_throughput(bool is_full_gc,
853 size_t* desired_eden_size_ptr) {
854
855 // Add some checks for a threshold for a change. For example,
856 // a change less than the required alignment is probably not worth
857 // attempting.
858
859 if ((gc_cost() + mutator_cost()) == 0.0) {
860 return;
861 }
862
863 if (PrintAdaptiveSizePolicy && Verbose) {
864 gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_eden_for_throughput("
865 "is_full: %d, cur_eden: " SIZE_FORMAT "): ",
866 is_full_gc, *desired_eden_size_ptr);
867 gclog_or_tty->print_cr("mutator_cost %f major_gc_cost %f "
868 "minor_gc_cost %f", mutator_cost(), major_gc_cost(), minor_gc_cost());
869 }
870
871 // Young generation
872 size_t scaled_eden_heap_delta = 0;
873 // Can the increment to the generation be scaled?
874 if (gc_cost() >= 0.0 && minor_gc_cost() >= 0.0) {
875 size_t eden_heap_delta =
876 eden_increment_with_supplement_aligned_up(*desired_eden_size_ptr);
877 double scale_by_ratio = minor_gc_cost() / gc_cost();
878 assert(scale_by_ratio <= 1.0 && scale_by_ratio >= 0.0, "Scaling is wrong");
879 scaled_eden_heap_delta =
880 (size_t) (scale_by_ratio * (double) eden_heap_delta);
881 if (PrintAdaptiveSizePolicy && Verbose) {
882 gclog_or_tty->print_cr(
883 "Scaled eden increment: " SIZE_FORMAT " by %f down to "
884 SIZE_FORMAT,
885 eden_heap_delta, scale_by_ratio, scaled_eden_heap_delta);
886 }
887 } else if (minor_gc_cost() >= 0.0) {
888 // Scaling is not going to work. If the minor gc time is the
889 // larger, give it a full increment.
890 if (minor_gc_cost() > major_gc_cost()) {
891 scaled_eden_heap_delta =
892 eden_increment_with_supplement_aligned_up(*desired_eden_size_ptr);
893 }
894 } else {
895 // Don't expect to get here but it's ok if it does
896 // in the product build since the delta will be 0
897 // and nothing will change.
898 assert(false, "Unexpected value for gc costs");
899 }
900
901 // Use a heuristic for some number of collections to give
902 // the averages time to settle down.
903 switch (AdaptiveSizeThroughPutPolicy) {
904 case 1:
905 if (minor_collection_estimator()->increment_will_decrease() ||
906 (_young_gen_change_for_minor_throughput
919 // EXPERIMENTAL ADJUSTMENT
920 // Record that decreasing the young gen size would decrease
921 // the minor collection cost but don't do it.
922 // *desired_eden_size_ptr = _eden_size -
923 // eden_decrement_aligned_down(*desired_eden_size_ptr);
924 set_change_young_gen_for_throughput(
925 decrease_young_gen_for_througput_true);
926 }
927 break;
928 default:
929 if ((*desired_eden_size_ptr + scaled_eden_heap_delta) >
930 *desired_eden_size_ptr) {
931 *desired_eden_size_ptr =
932 *desired_eden_size_ptr + scaled_eden_heap_delta;
933 }
934 set_change_young_gen_for_throughput(
935 increase_young_gen_for_througput_true);
936 _young_gen_change_for_minor_throughput++;
937 }
938
939 if (PrintAdaptiveSizePolicy && Verbose) {
940 gclog_or_tty->print_cr(
941 "adjusting eden for throughput (avg %f goal %f). desired_eden_size "
942 SIZE_FORMAT " eden delta " SIZE_FORMAT "\n",
943 mutator_cost(), _throughput_goal,
944 *desired_eden_size_ptr, scaled_eden_heap_delta);
945 }
946 }
947
948 size_t PSAdaptiveSizePolicy::adjust_promo_for_footprint(
949 size_t desired_promo_size, size_t desired_sum) {
950 assert(desired_promo_size <= desired_sum, "Inconsistent parameters");
951 set_decrease_for_footprint(decrease_old_gen_for_footprint_true);
952
953 size_t change = promo_decrement(desired_promo_size);
954 change = scale_down(change, desired_promo_size, desired_sum);
955
956 size_t reduced_size = desired_promo_size - change;
957
958 if (PrintAdaptiveSizePolicy && Verbose) {
959 gclog_or_tty->print_cr(
960 "AdaptiveSizePolicy::adjust_promo_for_footprint "
961 "adjusting tenured gen for footprint. "
962 "starting promo size " SIZE_FORMAT
963 " reduced promo size " SIZE_FORMAT
964 " promo delta " SIZE_FORMAT,
965 desired_promo_size, reduced_size, change );
966 }
967
968 assert(reduced_size <= desired_promo_size, "Inconsistent result");
969 return reduced_size;
970 }
971
972 size_t PSAdaptiveSizePolicy::adjust_eden_for_footprint(
973 size_t desired_eden_size, size_t desired_sum) {
974 assert(desired_eden_size <= desired_sum, "Inconsistent parameters");
975 set_decrease_for_footprint(decrease_young_gen_for_footprint_true);
976
977 size_t change = eden_decrement(desired_eden_size);
978 change = scale_down(change, desired_eden_size, desired_sum);
979
980 size_t reduced_size = desired_eden_size - change;
981
982 if (PrintAdaptiveSizePolicy && Verbose) {
983 gclog_or_tty->print_cr(
984 "AdaptiveSizePolicy::adjust_eden_for_footprint "
985 "adjusting eden for footprint. "
986 " starting eden size " SIZE_FORMAT
987 " reduced eden size " SIZE_FORMAT
988 " eden delta " SIZE_FORMAT,
989 desired_eden_size, reduced_size, change);
990 }
991
992 assert(reduced_size <= desired_eden_size, "Inconsistent result");
993 return reduced_size;
994 }
995
996 // Scale down "change" by the factor
997 // part / total
998 // Don't align the results.
999
1000 size_t PSAdaptiveSizePolicy::scale_down(size_t change,
1001 double part,
1002 double total) {
1003 assert(part <= total, "Inconsistent input");
1004 size_t reduced_change = change;
1005 if (total > 0) {
1006 double fraction = part / total;
1007 reduced_change = (size_t) (fraction * (double) change);
1008 }
1009 assert(reduced_change <= change, "Inconsistent result");
1010 return reduced_change;
1170 }
1171
1172 // Finally, increment or decrement the tenuring threshold, as decided above.
1173 // We test for decrementing first, as we might have hit the target size
1174 // limit.
1175 if (decr_tenuring_threshold && !(AlwaysTenure || NeverTenure)) {
1176 if (tenuring_threshold > 1) {
1177 tenuring_threshold--;
1178 }
1179 } else if (incr_tenuring_threshold && !(AlwaysTenure || NeverTenure)) {
1180 if (tenuring_threshold < MaxTenuringThreshold) {
1181 tenuring_threshold++;
1182 }
1183 }
1184
1185 // We keep a running average of the amount promoted which is used
1186 // to decide when we should collect the old generation (when
1187 // the amount of old gen free space is less than what we expect to
1188 // promote).
1189
1190 if (PrintAdaptiveSizePolicy) {
1191 // A little more detail if Verbose is on
1192 if (Verbose) {
1193 gclog_or_tty->print( " avg_survived: %f"
1194 " avg_deviation: %f",
1195 _avg_survived->average(),
1196 _avg_survived->deviation());
1197 }
1198
1199 gclog_or_tty->print( " avg_survived_padded_avg: %f",
1200 _avg_survived->padded_average());
1201
1202 if (Verbose) {
1203 gclog_or_tty->print( " avg_promoted_avg: %f"
1204 " avg_promoted_dev: %f",
1205 avg_promoted()->average(),
1206 avg_promoted()->deviation());
1207 }
1208
1209 gclog_or_tty->print_cr( " avg_promoted_padded_avg: %f"
1210 " avg_pretenured_padded_avg: %f"
1211 " tenuring_thresh: %d"
1212 " target_size: " SIZE_FORMAT,
1213 avg_promoted()->padded_average(),
1214 _avg_pretenured->padded_average(),
1215 tenuring_threshold, target_size);
1216 }
1217
1218 set_survivor_size(target_size);
1219
1220 return tenuring_threshold;
1221 }
1222
1223 void PSAdaptiveSizePolicy::update_averages(bool is_survivor_overflow,
1224 size_t survived,
1225 size_t promoted) {
1226 // Update averages
1227 if (!is_survivor_overflow) {
1228 // Keep running averages on how much survived
1229 _avg_survived->sample(survived);
1230 } else {
1231 size_t survived_guess = survived + promoted;
1232 _avg_survived->sample(survived_guess);
1233 }
1234 avg_promoted()->sample(promoted);
1235
1236 if (PrintAdaptiveSizePolicy) {
1237 gclog_or_tty->print_cr(
1238 "AdaptiveSizePolicy::update_averages:"
1239 " survived: " SIZE_FORMAT
1240 " promoted: " SIZE_FORMAT
1241 " overflow: %s",
1242 survived, promoted, is_survivor_overflow ? "true" : "false");
1243 }
1244 }
1245
1246 bool PSAdaptiveSizePolicy::print_adaptive_size_policy_on(outputStream* st)
1247 const {
1248
1249 if (!UseAdaptiveSizePolicy) return false;
1250
1251 return AdaptiveSizePolicy::print_adaptive_size_policy_on(
1252 st,
1253 PSScavenge::tenuring_threshold());
1254 }
1255
1256 #ifndef PRODUCT
1257
1258 void TestOldFreeSpaceCalculation_test() {
1259 assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 20) == 25, "Calculation of free memory failed");
1260 assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 50) == 100, "Calculation of free memory failed");
1261 assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 60) == 150, "Calculation of free memory failed");
1262 assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 75) == 300, "Calculation of free memory failed");
1263 assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 20) == 100, "Calculation of free memory failed");
1264 assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 50) == 400, "Calculation of free memory failed");
1265 assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 60) == 600, "Calculation of free memory failed");
1266 assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 75) == 1200, "Calculation of free memory failed");
1267 }
1268
1269 #endif /* !PRODUCT */
|
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/parallel/parallelScavengeHeap.hpp"
27 #include "gc/parallel/psAdaptiveSizePolicy.hpp"
28 #include "gc/parallel/psGCAdaptivePolicyCounters.hpp"
29 #include "gc/parallel/psScavenge.hpp"
30 #include "gc/shared/collectorPolicy.hpp"
31 #include "gc/shared/gcCause.hpp"
32 #include "gc/shared/gcPolicyCounters.hpp"
33 #include "logging/log.hpp"
34 #include "runtime/timer.hpp"
35 #include "utilities/top.hpp"
36
37 #include <math.h>
38
39 PSAdaptiveSizePolicy::PSAdaptiveSizePolicy(size_t init_eden_size,
40 size_t init_promo_size,
41 size_t init_survivor_size,
42 size_t space_alignment,
43 double gc_pause_goal_sec,
44 double gc_minor_pause_goal_sec,
45 uint gc_cost_ratio) :
46 AdaptiveSizePolicy(init_eden_size,
47 init_promo_size,
48 init_survivor_size,
49 gc_pause_goal_sec,
50 gc_cost_ratio),
51 _collection_cost_margin_fraction(AdaptiveSizePolicyCollectionCostMargin / 100.0),
52 _space_alignment(space_alignment),
53 _live_at_last_full_gc(init_promo_size),
143 if ((_latest_major_mutator_interval_seconds > 0.0) &&
144 (major_pause_in_seconds > 0.0)) {
145 double interval_in_seconds =
146 _latest_major_mutator_interval_seconds + major_pause_in_seconds;
147 collection_cost =
148 major_pause_in_seconds / interval_in_seconds;
149 avg_major_gc_cost()->sample(collection_cost);
150
151 // Sample for performance counter
152 _avg_major_interval->sample(interval_in_seconds);
153 }
154
155 // Calculate variables used to estimate pause time vs. gen sizes
156 double eden_size_in_mbytes = ((double)_eden_size)/((double)M);
157 double promo_size_in_mbytes = ((double)_promo_size)/((double)M);
158 _major_pause_old_estimator->update(promo_size_in_mbytes,
159 major_pause_in_ms);
160 _major_pause_young_estimator->update(eden_size_in_mbytes,
161 major_pause_in_ms);
162
163 log_trace(gc, ergo)("psAdaptiveSizePolicy::major_collection_end: major gc cost: %f average: %f",
164 collection_cost,avg_major_gc_cost()->average());
165 log_trace(gc, ergo)(" major pause: %f major period %f",
166 major_pause_in_ms, _latest_major_mutator_interval_seconds * MILLIUNITS);
167
168 // Calculate variable used to estimate collection cost vs. gen sizes
169 assert(collection_cost >= 0.0, "Expected to be non-negative");
170 _major_collection_estimator->update(promo_size_in_mbytes,
171 collection_cost);
172 }
173
174 // Update the amount live at the end of a full GC
175 _live_at_last_full_gc = amount_live;
176
177 // The policy does not have enough data until at least some major collections
178 // have been done.
179 if (_avg_major_pause->count() >= AdaptiveSizePolicyReadyThreshold) {
180 _old_gen_policy_is_ready = true;
181 }
182
183 // Interval times use this timer to measure the interval that
184 // the mutator runs. Reset after the GC pause has been measured.
185 _major_timer.reset();
186 _major_timer.start();
187 }
188
189 // If the remaining free space in the old generation is less that
190 // that expected to be needed by the next collection, do a full
191 // collection now.
192 bool PSAdaptiveSizePolicy::should_full_GC(size_t old_free_in_bytes) {
193
194 // A similar test is done in the scavenge's should_attempt_scavenge(). If
195 // this is changed, decide if that test should also be changed.
196 bool result = padded_average_promoted_in_bytes() > (float) old_free_in_bytes;
197 log_trace(gc, ergo)("%s after scavenge average_promoted " SIZE_FORMAT " padded_average_promoted " SIZE_FORMAT " free in old gen " SIZE_FORMAT,
198 result ? "Full" : "No full",
199 (size_t) average_promoted_in_bytes(),
200 (size_t) padded_average_promoted_in_bytes(),
201 old_free_in_bytes);
202 return result;
203 }
204
205 void PSAdaptiveSizePolicy::clear_generation_free_space_flags() {
206
207 AdaptiveSizePolicy::clear_generation_free_space_flags();
208
209 set_change_old_gen_for_min_pauses(0);
210
211 set_change_young_gen_for_maj_pauses(0);
212 }
213
214 // If this is not a full GC, only test and modify the young generation.
215
216 void PSAdaptiveSizePolicy::compute_generations_free_space(
217 size_t young_live,
218 size_t eden_live,
219 size_t old_live,
220 size_t cur_eden,
221 size_t max_old_gen_size,
333 assert(minor_cost >= 0.0, "minor cost is < 0.0");
334 // Try to reduce the GC times.
335 adjust_eden_for_throughput(is_full_gc, &desired_eden_size);
336
337 } else {
338
339 // Be conservative about reducing the footprint.
340 // Do a minimum number of major collections first.
341 // Have reasonable averages for major and minor collections costs.
342 if (UseAdaptiveSizePolicyFootprintGoal &&
343 young_gen_policy_is_ready() &&
344 avg_major_gc_cost()->average() >= 0.0 &&
345 avg_minor_gc_cost()->average() >= 0.0) {
346 size_t desired_sum = desired_eden_size + desired_promo_size;
347 desired_eden_size = adjust_eden_for_footprint(desired_eden_size, desired_sum);
348 }
349 }
350
351 // Note we make the same tests as in the code block below; the code
352 // seems a little easier to read with the printing in another block.
353 if (desired_eden_size > eden_limit) {
354 log_debug(gc, ergo)(
355 "PSAdaptiveSizePolicy::compute_eden_space_size limits:"
356 " desired_eden_size: " SIZE_FORMAT
357 " old_eden_size: " SIZE_FORMAT
358 " eden_limit: " SIZE_FORMAT
359 " cur_eden: " SIZE_FORMAT
360 " max_eden_size: " SIZE_FORMAT
361 " avg_young_live: " SIZE_FORMAT,
362 desired_eden_size, _eden_size, eden_limit, cur_eden,
363 max_eden_size, (size_t)avg_young_live()->average());
364 }
365 if (gc_cost() > gc_cost_limit) {
366 log_debug(gc, ergo)(
367 "PSAdaptiveSizePolicy::compute_eden_space_size: gc time limit"
368 " gc_cost: %f "
369 " GCTimeLimit: " UINTX_FORMAT,
370 gc_cost(), GCTimeLimit);
371 }
372
373 // Align everything and make a final limit check
374 desired_eden_size = align_size_up(desired_eden_size, _space_alignment);
375 desired_eden_size = MAX2(desired_eden_size, _space_alignment);
376
377 eden_limit = align_size_down(eden_limit, _space_alignment);
378
379 // And one last limit check, now that we've aligned things.
380 if (desired_eden_size > eden_limit) {
381 // If the policy says to get a larger eden but
382 // is hitting the limit, don't decrease eden.
383 // This can lead to a general drifting down of the
384 // eden size. Let the tenuring calculation push more
385 // into the old gen.
386 desired_eden_size = MAX2(eden_limit, cur_eden);
387 }
388
389 log_debug(gc, ergo)("PSAdaptiveSizePolicy::compute_eden_space_size: costs minor_time: %f major_cost: %f mutator_cost: %f throughput_goal: %f",
390 minor_gc_cost(), major_gc_cost(), mutator_cost(), _throughput_goal);
391
392 log_trace(gc, ergo)("Minor_pause: %f major_pause: %f minor_interval: %f major_interval: %fpause_goal: %f",
393 _avg_minor_pause->padded_average(),
394 _avg_major_pause->padded_average(),
395 _avg_minor_interval->average(),
396 _avg_major_interval->average(),
397 gc_pause_goal_sec());
398
399 log_debug(gc, ergo)("Live_space: " SIZE_FORMAT " free_space: " SIZE_FORMAT,
400 live_space(), free_space());
401
402 log_trace(gc, ergo)("Base_footprint: " SIZE_FORMAT " avg_young_live: " SIZE_FORMAT " avg_old_live: " SIZE_FORMAT,
403 (size_t)_avg_base_footprint->average(),
404 (size_t)avg_young_live()->average(),
405 (size_t)avg_old_live()->average());
406
407 log_debug(gc, ergo)("Old eden_size: " SIZE_FORMAT " desired_eden_size: " SIZE_FORMAT,
408 _eden_size, desired_eden_size);
409
410 set_eden_size(desired_eden_size);
411 }
412
413 void PSAdaptiveSizePolicy::compute_old_gen_free_space(
414 size_t old_live,
415 size_t cur_eden,
416 size_t max_old_gen_size,
417 bool is_full_gc) {
418
419 // Update statistics
420 // Time statistics are updated as we go, update footprint stats here
421 if (is_full_gc) {
422 // old_live is only accurate after a full gc
423 avg_old_live()->sample(old_live);
424 }
425
426 // This code used to return if the policy was not ready , i.e.,
427 // policy_is_ready() returning false. The intent was that
428 // decisions below needed major collection times and so could
509 }
510 } else {
511
512 // Be conservative about reducing the footprint.
513 // Do a minimum number of major collections first.
514 // Have reasonable averages for major and minor collections costs.
515 if (UseAdaptiveSizePolicyFootprintGoal &&
516 young_gen_policy_is_ready() &&
517 avg_major_gc_cost()->average() >= 0.0 &&
518 avg_minor_gc_cost()->average() >= 0.0) {
519 if (is_full_gc) {
520 set_decide_at_full_gc(decide_at_full_gc_true);
521 size_t desired_sum = desired_eden_size + desired_promo_size;
522 desired_promo_size = adjust_promo_for_footprint(desired_promo_size, desired_sum);
523 }
524 }
525 }
526
527 // Note we make the same tests as in the code block below; the code
528 // seems a little easier to read with the printing in another block.
529 if (desired_promo_size > promo_limit) {
530 // "free_in_old_gen" was the original value for used for promo_limit
531 size_t free_in_old_gen = (size_t)(max_old_gen_size - avg_old_live()->average());
532 log_debug(gc, ergo)(
533 "PSAdaptiveSizePolicy::compute_old_gen_free_space limits:"
534 " desired_promo_size: " SIZE_FORMAT
535 " promo_limit: " SIZE_FORMAT
536 " free_in_old_gen: " SIZE_FORMAT
537 " max_old_gen_size: " SIZE_FORMAT
538 " avg_old_live: " SIZE_FORMAT,
539 desired_promo_size, promo_limit, free_in_old_gen,
540 max_old_gen_size, (size_t) avg_old_live()->average());
541 }
542 if (gc_cost() > gc_cost_limit) {
543 log_debug(gc, ergo)(
544 "PSAdaptiveSizePolicy::compute_old_gen_free_space: gc time limit"
545 " gc_cost: %f "
546 " GCTimeLimit: " UINTX_FORMAT,
547 gc_cost(), GCTimeLimit);
548 }
549
550 // Align everything and make a final limit check
551 desired_promo_size = align_size_up(desired_promo_size, _space_alignment);
552 desired_promo_size = MAX2(desired_promo_size, _space_alignment);
553
554 promo_limit = align_size_down(promo_limit, _space_alignment);
555
556 // And one last limit check, now that we've aligned things.
557 desired_promo_size = MIN2(desired_promo_size, promo_limit);
558
559 // Timing stats
560 log_debug(gc, ergo)("PSAdaptiveSizePolicy::compute_old_gen_free_space: costs minor_time: %f major_cost: %f mutator_cost: %f throughput_goal: %f",
561 minor_gc_cost(), major_gc_cost(), mutator_cost(), _throughput_goal);
562
563 log_trace(gc, ergo)("Minor_pause: %f major_pause: %f minor_interval: %f major_interval: %f pause_goal: %f",
564 _avg_minor_pause->padded_average(),
565 _avg_major_pause->padded_average(),
566 _avg_minor_interval->average(),
567 _avg_major_interval->average(),
568 gc_pause_goal_sec());
569
570 // Footprint stats
571 log_debug(gc, ergo)("Live_space: " SIZE_FORMAT " free_space: " SIZE_FORMAT,
572 live_space(), free_space());
573
574 log_trace(gc, ergo)("Base_footprint: " SIZE_FORMAT " avg_young_live: " SIZE_FORMAT " avg_old_live: " SIZE_FORMAT,
575 (size_t)_avg_base_footprint->average(),
576 (size_t)avg_young_live()->average(),
577 (size_t)avg_old_live()->average());
578
579 log_debug(gc, ergo)("Old promo_size: " SIZE_FORMAT " desired_promo_size: " SIZE_FORMAT,
580 _promo_size, desired_promo_size);
581
582 set_promo_size(desired_promo_size);
583 }
584
585 void PSAdaptiveSizePolicy::decay_supplemental_growth(bool is_full_gc) {
586 // Decay the supplemental increment? Decay the supplement growth
587 // factor even if it is not used. It is only meant to give a boost
588 // to the initial growth and if it is not used, then it was not
589 // needed.
590 if (is_full_gc) {
591 // Don't wait for the threshold value for the major collections. If
592 // here, the supplemental growth term was used and should decay.
593 if ((_avg_major_pause->count() % TenuredGenerationSizeSupplementDecay)
594 == 0) {
595 _old_gen_size_increment_supplement =
596 _old_gen_size_increment_supplement >> 1;
597 }
598 } else {
599 if ((_avg_minor_pause->count() >= AdaptiveSizePolicyReadyThreshold) &&
600 (_avg_minor_pause->count() % YoungGenerationSizeSupplementDecay) == 0) {
639
640 if (_avg_minor_pause->padded_average() <= _avg_major_pause->padded_average() && is_full_gc) {
641 // Adjust for the major pause time only at full gc's because the
642 // affects of a change can only be seen at full gc's.
643
644 // Reduce old generation size to reduce pause?
645 if (major_pause_old_estimator()->decrement_will_decrease()) {
646 // reduce old generation size
647 set_change_old_gen_for_maj_pauses(decrease_old_gen_for_maj_pauses_true);
648 promo_heap_delta = promo_decrement_aligned_down(*desired_promo_size_ptr);
649 *desired_promo_size_ptr = _promo_size - promo_heap_delta;
650 } else {
651 // EXPERIMENTAL ADJUSTMENT
652 // Only record that the estimator indicated such an action.
653 // *desired_promo_size_ptr = _promo_size +
654 // promo_increment_aligned_up(*desired_promo_size_ptr);
655 set_change_old_gen_for_maj_pauses(increase_old_gen_for_maj_pauses_true);
656 }
657 }
658
659 log_trace(gc, ergo)(
660 "PSAdaptiveSizePolicy::adjust_promo_for_pause_time "
661 "adjusting gen sizes for major pause (avg %f goal %f). "
662 "desired_promo_size " SIZE_FORMAT " promo delta " SIZE_FORMAT,
663 _avg_major_pause->average(), gc_pause_goal_sec(),
664 *desired_promo_size_ptr, promo_heap_delta);
665 }
666
667 void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(bool is_full_gc,
668 size_t* desired_promo_size_ptr,
669 size_t* desired_eden_size_ptr) {
670
671 size_t eden_heap_delta = 0;
672 // Add some checks for a threshold for a change. For example,
673 // a change less than the required alignment is probably not worth
674 // attempting.
675 if (_avg_minor_pause->padded_average() > _avg_major_pause->padded_average()) {
676 adjust_eden_for_minor_pause_time(is_full_gc, desired_eden_size_ptr);
677 }
678 log_trace(gc, ergo)(
679 "PSAdaptiveSizePolicy::adjust_eden_for_pause_time "
680 "adjusting gen sizes for major pause (avg %f goal %f). "
681 "desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT,
682 _avg_major_pause->average(), gc_pause_goal_sec(),
683 *desired_eden_size_ptr, eden_heap_delta);
684 }
685
686 void PSAdaptiveSizePolicy::adjust_promo_for_throughput(bool is_full_gc,
687 size_t* desired_promo_size_ptr) {
688
689 // Add some checks for a threshold for a change. For example,
690 // a change less than the required alignment is probably not worth
691 // attempting.
692
693 if ((gc_cost() + mutator_cost()) == 0.0) {
694 return;
695 }
696
697 log_trace(gc, ergo)("PSAdaptiveSizePolicy::adjust_promo_for_throughput(is_full: %d, promo: " SIZE_FORMAT "): mutator_cost %f major_gc_cost %f minor_gc_cost %f",
698 is_full_gc,
699 *desired_promo_size_ptr,
700 mutator_cost(),
701 major_gc_cost(),
702 minor_gc_cost());
703
704 // Tenured generation
705 if (is_full_gc) {
706 // Calculate the change to use for the tenured gen.
707 size_t scaled_promo_heap_delta = 0;
708 // Can the increment to the generation be scaled?
709 if (gc_cost() >= 0.0 && major_gc_cost() >= 0.0) {
710 size_t promo_heap_delta =
711 promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr);
712 double scale_by_ratio = major_gc_cost() / gc_cost();
713 scaled_promo_heap_delta =
714 (size_t) (scale_by_ratio * (double) promo_heap_delta);
715 log_trace(gc, ergo)("Scaled tenured increment: " SIZE_FORMAT " by %f down to " SIZE_FORMAT,
716 promo_heap_delta, scale_by_ratio, scaled_promo_heap_delta);
717 } else if (major_gc_cost() >= 0.0) {
718 // Scaling is not going to work. If the major gc time is the
719 // larger, give it a full increment.
720 if (major_gc_cost() >= minor_gc_cost()) {
721 scaled_promo_heap_delta =
722 promo_increment_with_supplement_aligned_up(*desired_promo_size_ptr);
723 }
724 } else {
725 // Don't expect to get here but it's ok if it does
726 // in the product build since the delta will be 0
727 // and nothing will change.
728 assert(false, "Unexpected value for gc costs");
729 }
730
731 switch (AdaptiveSizeThroughPutPolicy) {
732 case 1:
733 // Early in the run the statistics might not be good. Until
734 // a specific number of collections have been, use the heuristic
735 // that a larger generation size means lower collection costs.
736 if (major_collection_estimator()->increment_will_decrease() ||
750 // the major collection cost but don't do it.
751 // *desired_promo_size_ptr = _promo_size -
752 // promo_decrement_aligned_down(*desired_promo_size_ptr);
753 set_change_old_gen_for_throughput(
754 decrease_old_gen_for_throughput_true);
755 }
756
757 break;
758 default:
759 // Simplest strategy
760 if ((*desired_promo_size_ptr + scaled_promo_heap_delta) >
761 *desired_promo_size_ptr) {
762 *desired_promo_size_ptr = *desired_promo_size_ptr +
763 scaled_promo_heap_delta;
764 }
765 set_change_old_gen_for_throughput(
766 increase_old_gen_for_throughput_true);
767 _old_gen_change_for_major_throughput++;
768 }
769
770 log_trace(gc, ergo)("Adjusting tenured gen for throughput (avg %f goal %f). desired_promo_size " SIZE_FORMAT " promo_delta " SIZE_FORMAT ,
771 mutator_cost(),
772 _throughput_goal,
773 *desired_promo_size_ptr, scaled_promo_heap_delta);
774 }
775 }
776
777 void PSAdaptiveSizePolicy::adjust_eden_for_throughput(bool is_full_gc,
778 size_t* desired_eden_size_ptr) {
779
780 // Add some checks for a threshold for a change. For example,
781 // a change less than the required alignment is probably not worth
782 // attempting.
783
784 if ((gc_cost() + mutator_cost()) == 0.0) {
785 return;
786 }
787
788 log_trace(gc, ergo)("PSAdaptiveSizePolicy::adjust_eden_for_throughput(is_full: %d, cur_eden: " SIZE_FORMAT "): mutator_cost %f major_gc_cost %f minor_gc_cost %f",
789 is_full_gc,
790 *desired_eden_size_ptr,
791 mutator_cost(),
792 major_gc_cost(),
793 minor_gc_cost());
794
795 // Young generation
796 size_t scaled_eden_heap_delta = 0;
797 // Can the increment to the generation be scaled?
798 if (gc_cost() >= 0.0 && minor_gc_cost() >= 0.0) {
799 size_t eden_heap_delta =
800 eden_increment_with_supplement_aligned_up(*desired_eden_size_ptr);
801 double scale_by_ratio = minor_gc_cost() / gc_cost();
802 assert(scale_by_ratio <= 1.0 && scale_by_ratio >= 0.0, "Scaling is wrong");
803 scaled_eden_heap_delta =
804 (size_t) (scale_by_ratio * (double) eden_heap_delta);
805 log_trace(gc, ergo)("Scaled eden increment: " SIZE_FORMAT " by %f down to " SIZE_FORMAT,
806 eden_heap_delta, scale_by_ratio, scaled_eden_heap_delta);
807 } else if (minor_gc_cost() >= 0.0) {
808 // Scaling is not going to work. If the minor gc time is the
809 // larger, give it a full increment.
810 if (minor_gc_cost() > major_gc_cost()) {
811 scaled_eden_heap_delta =
812 eden_increment_with_supplement_aligned_up(*desired_eden_size_ptr);
813 }
814 } else {
815 // Don't expect to get here but it's ok if it does
816 // in the product build since the delta will be 0
817 // and nothing will change.
818 assert(false, "Unexpected value for gc costs");
819 }
820
821 // Use a heuristic for some number of collections to give
822 // the averages time to settle down.
823 switch (AdaptiveSizeThroughPutPolicy) {
824 case 1:
825 if (minor_collection_estimator()->increment_will_decrease() ||
826 (_young_gen_change_for_minor_throughput
839 // EXPERIMENTAL ADJUSTMENT
840 // Record that decreasing the young gen size would decrease
841 // the minor collection cost but don't do it.
842 // *desired_eden_size_ptr = _eden_size -
843 // eden_decrement_aligned_down(*desired_eden_size_ptr);
844 set_change_young_gen_for_throughput(
845 decrease_young_gen_for_througput_true);
846 }
847 break;
848 default:
849 if ((*desired_eden_size_ptr + scaled_eden_heap_delta) >
850 *desired_eden_size_ptr) {
851 *desired_eden_size_ptr =
852 *desired_eden_size_ptr + scaled_eden_heap_delta;
853 }
854 set_change_young_gen_for_throughput(
855 increase_young_gen_for_througput_true);
856 _young_gen_change_for_minor_throughput++;
857 }
858
859 log_trace(gc, ergo)("Adjusting eden for throughput (avg %f goal %f). desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT,
860 mutator_cost(), _throughput_goal, *desired_eden_size_ptr, scaled_eden_heap_delta);
861 }
862
863 size_t PSAdaptiveSizePolicy::adjust_promo_for_footprint(
864 size_t desired_promo_size, size_t desired_sum) {
865 assert(desired_promo_size <= desired_sum, "Inconsistent parameters");
866 set_decrease_for_footprint(decrease_old_gen_for_footprint_true);
867
868 size_t change = promo_decrement(desired_promo_size);
869 change = scale_down(change, desired_promo_size, desired_sum);
870
871 size_t reduced_size = desired_promo_size - change;
872
873 log_trace(gc, ergo)(
874 "AdaptiveSizePolicy::adjust_promo_for_footprint "
875 "adjusting tenured gen for footprint. "
876 "starting promo size " SIZE_FORMAT
877 " reduced promo size " SIZE_FORMAT
878 " promo delta " SIZE_FORMAT,
879 desired_promo_size, reduced_size, change );
880
881 assert(reduced_size <= desired_promo_size, "Inconsistent result");
882 return reduced_size;
883 }
884
885 size_t PSAdaptiveSizePolicy::adjust_eden_for_footprint(
886 size_t desired_eden_size, size_t desired_sum) {
887 assert(desired_eden_size <= desired_sum, "Inconsistent parameters");
888 set_decrease_for_footprint(decrease_young_gen_for_footprint_true);
889
890 size_t change = eden_decrement(desired_eden_size);
891 change = scale_down(change, desired_eden_size, desired_sum);
892
893 size_t reduced_size = desired_eden_size - change;
894
895 log_trace(gc, ergo)(
896 "AdaptiveSizePolicy::adjust_eden_for_footprint "
897 "adjusting eden for footprint. "
898 " starting eden size " SIZE_FORMAT
899 " reduced eden size " SIZE_FORMAT
900 " eden delta " SIZE_FORMAT,
901 desired_eden_size, reduced_size, change);
902
903 assert(reduced_size <= desired_eden_size, "Inconsistent result");
904 return reduced_size;
905 }
906
907 // Scale down "change" by the factor
908 // part / total
909 // Don't align the results.
910
911 size_t PSAdaptiveSizePolicy::scale_down(size_t change,
912 double part,
913 double total) {
914 assert(part <= total, "Inconsistent input");
915 size_t reduced_change = change;
916 if (total > 0) {
917 double fraction = part / total;
918 reduced_change = (size_t) (fraction * (double) change);
919 }
920 assert(reduced_change <= change, "Inconsistent result");
921 return reduced_change;
1081 }
1082
1083 // Finally, increment or decrement the tenuring threshold, as decided above.
1084 // We test for decrementing first, as we might have hit the target size
1085 // limit.
1086 if (decr_tenuring_threshold && !(AlwaysTenure || NeverTenure)) {
1087 if (tenuring_threshold > 1) {
1088 tenuring_threshold--;
1089 }
1090 } else if (incr_tenuring_threshold && !(AlwaysTenure || NeverTenure)) {
1091 if (tenuring_threshold < MaxTenuringThreshold) {
1092 tenuring_threshold++;
1093 }
1094 }
1095
1096 // We keep a running average of the amount promoted which is used
1097 // to decide when we should collect the old generation (when
1098 // the amount of old gen free space is less than what we expect to
1099 // promote).
1100
1101 log_trace(gc, ergo)("avg_survived: %f avg_deviation: %f", _avg_survived->average(), _avg_survived->deviation());
1102 log_debug(gc, ergo)("avg_survived_padded_avg: %f", _avg_survived->padded_average());
1103
1104 log_trace(gc, ergo)("avg_promoted_avg: %f avg_promoted_dev: %f", avg_promoted()->average(), avg_promoted()->deviation());
1105 log_debug(gc, ergo)("avg_promoted_padded_avg: %f avg_pretenured_padded_avg: %f tenuring_thresh: %d target_size: " SIZE_FORMAT,
1106 avg_promoted()->padded_average(),
1107 _avg_pretenured->padded_average(),
1108 tenuring_threshold, target_size);
1109
1110 set_survivor_size(target_size);
1111
1112 return tenuring_threshold;
1113 }
1114
1115 void PSAdaptiveSizePolicy::update_averages(bool is_survivor_overflow,
1116 size_t survived,
1117 size_t promoted) {
1118 // Update averages
1119 if (!is_survivor_overflow) {
1120 // Keep running averages on how much survived
1121 _avg_survived->sample(survived);
1122 } else {
1123 size_t survived_guess = survived + promoted;
1124 _avg_survived->sample(survived_guess);
1125 }
1126 avg_promoted()->sample(promoted);
1127
1128 log_trace(gc, ergo)("AdaptiveSizePolicy::update_averages: survived: " SIZE_FORMAT " promoted: " SIZE_FORMAT " overflow: %s",
1129 survived, promoted, is_survivor_overflow ? "true" : "false");
1130 }
1131
1132 bool PSAdaptiveSizePolicy::print() const {
1133
1134 if (!UseAdaptiveSizePolicy) {
1135 return false;
1136 }
1137
1138 if (AdaptiveSizePolicy::print()) {
1139 AdaptiveSizePolicy::print_tenuring_threshold(PSScavenge::tenuring_threshold());
1140 return true;
1141 }
1142
1143 return false;
1144 }
1145
1146 #ifndef PRODUCT
1147
1148 void TestOldFreeSpaceCalculation_test() {
1149 assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 20) == 25, "Calculation of free memory failed");
1150 assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 50) == 100, "Calculation of free memory failed");
1151 assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 60) == 150, "Calculation of free memory failed");
1152 assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(100, 75) == 300, "Calculation of free memory failed");
1153 assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 20) == 100, "Calculation of free memory failed");
1154 assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 50) == 400, "Calculation of free memory failed");
1155 assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 60) == 600, "Calculation of free memory failed");
1156 assert(PSAdaptiveSizePolicy::calculate_free_based_on_live(400, 75) == 1200, "Calculation of free memory failed");
1157 }
1158
1159 #endif /* !PRODUCT */
|