src/share/vm/memory/collectorPolicy.cpp

Print this page
rev 5870 : 8033426: Scale initial NewSize using NewRatio if not set on command line
Summary: Now using NewRatio to size initial NewSize if not specified on commandline.
Reviewed-by: jmasa, jwilhelm


 429     // Bound the maximum size by NewSize below (since it historically
 430     // would have been NewSize and because the NewRatio calculation could
 431     // yield a size that is too small) and bound it by MaxNewSize above.
 432     // Ergonomics plays here by previously calculating the desired
 433     // NewSize and MaxNewSize.
 434     max_new_size = MIN2(MAX2(max_new_size, NewSize), MaxNewSize);
 435   }
 436   assert(max_new_size > 0, "All paths should set max_new_size");
 437 
 438   // Given the maximum gen0 size, determine the initial and
 439   // minimum gen0 sizes.
 440 
 441   if (_max_heap_byte_size == _min_heap_byte_size) {
 442     // The maximum and minimum heap sizes are the same so the generations
 443     // minimum and initial must be the same as its maximum.
 444     _min_gen0_size = max_new_size;
 445     _initial_gen0_size = max_new_size;
 446     _max_gen0_size = max_new_size;
 447   } else {
 448     size_t desired_new_size = 0;
 449     if (!FLAG_IS_DEFAULT(NewSize)) {
 450       // If NewSize is set ergonomically (for example by cms), it
 451       // would make sense to use it.  If it is used, also use it
 452       // to set the initial size.  Although there is no reason
 453       // the minimum size and the initial size have to be the same,
 454       // the current implementation gets into trouble during the calculation
 455       // of the tenured generation sizes if they are different.
 456       // Note that this makes the initial size and the minimum size
 457       // generally small compared to the NewRatio calculation.
 458       _min_gen0_size = NewSize;
 459       desired_new_size = NewSize;
 460       max_new_size = MAX2(max_new_size, NewSize);







 461     } else {
 462       // For the case where NewSize is the default, use NewRatio
 463       // to size the minimum and initial generation sizes.
 464       // Use the default NewSize as the floor for these values.  If
 465       // NewRatio is overly large, the resulting sizes can be too small.
 466       _min_gen0_size = MAX2(scale_by_NewRatio_aligned(_min_heap_byte_size), NewSize);
 467       desired_new_size =
 468         MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize);
 469     }
 470 
 471     assert(_min_gen0_size > 0, "Sanity check");
 472     _initial_gen0_size = desired_new_size;
 473     _max_gen0_size = max_new_size;
 474 
 475     // At this point the desirable initial and minimum sizes have been
 476     // determined without regard to the maximum sizes.
 477 
 478     // Bound the sizes by the corresponding overall heap sizes.
 479     _min_gen0_size = bound_minus_alignment(_min_gen0_size, _min_heap_byte_size);
 480     _initial_gen0_size = bound_minus_alignment(_initial_gen0_size, _initial_heap_byte_size);


 963   if (UseParNewGC) {
 964     _generations[0] = new GenerationSpec(Generation::ParNew, _initial_gen0_size, _max_gen0_size);
 965   } else {
 966     _generations[0] = new GenerationSpec(Generation::DefNew, _initial_gen0_size, _max_gen0_size);
 967   }
 968   _generations[1] = new GenerationSpec(Generation::MarkSweepCompact, _initial_gen1_size, _max_gen1_size);
 969 
 970   if (_generations[0] == NULL || _generations[1] == NULL) {
 971     vm_exit_during_initialization("Unable to allocate gen spec");
 972   }
 973 }
 974 
 975 void MarkSweepPolicy::initialize_gc_policy_counters() {
 976   // Initialize the policy counters - 2 collectors, 3 generations.
 977   if (UseParNewGC) {
 978     _gc_policy_counters = new GCPolicyCounters("ParNew:MSC", 2, 3);
 979   } else {
 980     _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 3);
 981   }
 982 }











































































































 429     // Bound the maximum size by NewSize below (since it historically
 430     // would have been NewSize and because the NewRatio calculation could
 431     // yield a size that is too small) and bound it by MaxNewSize above.
 432     // Ergonomics plays here by previously calculating the desired
 433     // NewSize and MaxNewSize.
 434     max_new_size = MIN2(MAX2(max_new_size, NewSize), MaxNewSize);
 435   }
 436   assert(max_new_size > 0, "All paths should set max_new_size");
 437 
 438   // Given the maximum gen0 size, determine the initial and
 439   // minimum gen0 sizes.
 440 
 441   if (_max_heap_byte_size == _min_heap_byte_size) {
 442     // The maximum and minimum heap sizes are the same so the generations
 443     // minimum and initial must be the same as its maximum.
 444     _min_gen0_size = max_new_size;
 445     _initial_gen0_size = max_new_size;
 446     _max_gen0_size = max_new_size;
 447   } else {
 448     size_t desired_new_size = 0;
 449     if (FLAG_IS_CMDLINE(NewSize)) {
 450       // If NewSize is set on the command line, we must use it as
 451       // the initial size and it also makes sense to use it as the
 452       // lower limit.





 453       _min_gen0_size = NewSize;
 454       desired_new_size = NewSize;
 455       max_new_size = MAX2(max_new_size, NewSize);
 456     } else if (FLAG_IS_ERGO(NewSize)) {
 457       // If NewSize is set ergonomically, we should use it as a lower
 458       // limit, but use NewRatio to calculate the initial size.
 459       _min_gen0_size = NewSize;
 460       desired_new_size =
 461         MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize);
 462       max_new_size = MAX2(max_new_size, NewSize);
 463     } else {
 464       // For the case where NewSize is the default, use NewRatio
 465       // to size the minimum and initial generation sizes.
 466       // Use the default NewSize as the floor for these values.  If
 467       // NewRatio is overly large, the resulting sizes can be too small.
 468       _min_gen0_size = MAX2(scale_by_NewRatio_aligned(_min_heap_byte_size), NewSize);
 469       desired_new_size =
 470         MAX2(scale_by_NewRatio_aligned(_initial_heap_byte_size), NewSize);
 471     }
 472 
 473     assert(_min_gen0_size > 0, "Sanity check");
 474     _initial_gen0_size = desired_new_size;
 475     _max_gen0_size = max_new_size;
 476 
 477     // At this point the desirable initial and minimum sizes have been
 478     // determined without regard to the maximum sizes.
 479 
 480     // Bound the sizes by the corresponding overall heap sizes.
 481     _min_gen0_size = bound_minus_alignment(_min_gen0_size, _min_heap_byte_size);
 482     _initial_gen0_size = bound_minus_alignment(_initial_gen0_size, _initial_heap_byte_size);


 965   if (UseParNewGC) {
 966     _generations[0] = new GenerationSpec(Generation::ParNew, _initial_gen0_size, _max_gen0_size);
 967   } else {
 968     _generations[0] = new GenerationSpec(Generation::DefNew, _initial_gen0_size, _max_gen0_size);
 969   }
 970   _generations[1] = new GenerationSpec(Generation::MarkSweepCompact, _initial_gen1_size, _max_gen1_size);
 971 
 972   if (_generations[0] == NULL || _generations[1] == NULL) {
 973     vm_exit_during_initialization("Unable to allocate gen spec");
 974   }
 975 }
 976 
 977 void MarkSweepPolicy::initialize_gc_policy_counters() {
 978   // Initialize the policy counters - 2 collectors, 3 generations.
 979   if (UseParNewGC) {
 980     _gc_policy_counters = new GCPolicyCounters("ParNew:MSC", 2, 3);
 981   } else {
 982     _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 3);
 983   }
 984 }
 985 
 986 /////////////// Unit tests ///////////////
 987 
 988 #ifndef PRODUCT
 989 // Testing that the NewSize flag is handled correct is hard because it
 990 // depends on so many other configurable variables. This test only tries to
 991 // verify that there are some basic rules for NewSize honored by the policies.
 992 class TestGenCollectorPolicy {
 993 public:
 994   static void test() {
 995     size_t flag_value;
 996 
 997     save_flags();
 998 
 999     // Set some limits that makes the math simple.
1000     FLAG_SET_ERGO(uintx, MaxHeapSize, 180 * M);
1001     FLAG_SET_ERGO(uintx, InitialHeapSize, 120 * M);
1002     Arguments::set_min_heap_size(40*M);
1003 
1004     // if NewSize set on command line should take for both min
1005     // and initial if less than min heap.
1006     flag_value = 20 * M;
1007     FLAG_SET_CMDLINE(uintx, NewSize, flag_value);
1008     verify_min(flag_value);
1009     verify_initial(flag_value);
1010 
1011     // If NewSize set on command line is set larger
1012     // than min heap size it will only take for initial.
1013     flag_value = 80*M;
1014     FLAG_SET_CMDLINE(uintx, NewSize, flag_value);
1015     verify_initial(flag_value);
1016 
1017     // If NewSize has been ergonomically set, the collector
1018     // policy should use it for min but calculate the initial
1019     // using NewRatio.
1020     flag_value = 20*M;
1021     FLAG_SET_ERGO(uintx, NewSize, flag_value);
1022     verify_min(flag_value);
1023     verify_scaled_initial(InitialHeapSize);
1024 
1025     restore_flags();
1026 
1027   }
1028 
1029   static void verify_min(size_t expected) {
1030     MarkSweepPolicy msp;
1031     msp.initialize_all();
1032 
1033     assert(msp.min_gen0_size() <= expected, err_msg("%zu  > %zu", msp.min_gen0_size(), expected));
1034   }
1035 
1036   static void verify_initial(size_t expected) {
1037     MarkSweepPolicy msp;
1038     msp.initialize_all();
1039 
1040     assert(msp.initial_gen0_size() == expected, err_msg("%zu != %zu", msp.initial_gen0_size(), expected));
1041   }
1042 
1043   static void verify_scaled_initial(size_t initial_heap_size) {
1044     MarkSweepPolicy msp;
1045     msp.initialize_all();
1046 
1047     size_t expected = msp.scale_by_NewRatio_aligned(initial_heap_size);
1048     assert(msp.initial_gen0_size() == expected, err_msg("%zu != %zu", msp.initial_gen0_size(), expected));
1049   }
1050 
1051 private:
1052   static size_t original_InitialHeapSize;
1053   static size_t original_MaxHeapSize;
1054   static size_t original_MaxNewSize;
1055   static size_t original_MinHeapDeltaBytes;
1056   static size_t original_NewSize;
1057   static size_t original_OldSize;
1058 
1059   static void save_flags() {
1060     original_InitialHeapSize   = InitialHeapSize;
1061     original_MaxHeapSize       = MaxHeapSize;
1062     original_MaxNewSize        = MaxNewSize;
1063     original_MinHeapDeltaBytes = MinHeapDeltaBytes;
1064     original_NewSize           = NewSize;
1065     original_OldSize           = OldSize;
1066   }
1067 
1068   static void restore_flags() {
1069     InitialHeapSize   = original_InitialHeapSize;
1070     MaxHeapSize       = original_MaxHeapSize;
1071     MaxNewSize        = original_MaxNewSize;
1072     MinHeapDeltaBytes = original_MinHeapDeltaBytes;
1073     NewSize           = original_NewSize;
1074     OldSize           = original_OldSize;
1075   }
1076 };
1077 
1078 size_t TestGenCollectorPolicy::original_InitialHeapSize   = 0;
1079 size_t TestGenCollectorPolicy::original_MaxHeapSize       = 0;
1080 size_t TestGenCollectorPolicy::original_MaxNewSize        = 0;
1081 size_t TestGenCollectorPolicy::original_MinHeapDeltaBytes = 0;
1082 size_t TestGenCollectorPolicy::original_NewSize           = 0;
1083 size_t TestGenCollectorPolicy::original_OldSize           = 0;
1084 
1085 void TestNewSize_test() {
1086   TestGenCollectorPolicy::test();
1087 }
1088 
1089 #endif