comparison src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 1717:688c3755d7af

6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check Summary: There are a few issues in the code that calculates whether to resize the heap and by how much: a) some calculations can overflow 32-bit size_t's, b) min_desired_capacity is not bounded by the max heap size, and c) the assrt that fires is in the wrong place. The fix also includes some tidying up of the related verbose code. Reviewed-by: ysr, jmasa
author tonyp
date Tue, 17 Aug 2010 14:40:00 -0400
parents 5f429ee79634
children bb847e31b836
comparison
equal deleted inserted replaced
1716:be3f9c242c9d 1717:688c3755d7af
1042 // pre-allocated to support collections, as "used". 1042 // pre-allocated to support collections, as "used".
1043 const size_t used_after_gc = used(); 1043 const size_t used_after_gc = used();
1044 const size_t capacity_after_gc = capacity(); 1044 const size_t capacity_after_gc = capacity();
1045 const size_t free_after_gc = capacity_after_gc - used_after_gc; 1045 const size_t free_after_gc = capacity_after_gc - used_after_gc;
1046 1046
1047 // This is enforced in arguments.cpp.
1048 assert(MinHeapFreeRatio <= MaxHeapFreeRatio,
1049 "otherwise the code below doesn't make sense");
1050
1047 // We don't have floating point command-line arguments 1051 // We don't have floating point command-line arguments
1048 const double minimum_free_percentage = (double) MinHeapFreeRatio / 100; 1052 const double minimum_free_percentage = (double) MinHeapFreeRatio / 100.0;
1049 const double maximum_used_percentage = 1.0 - minimum_free_percentage; 1053 const double maximum_used_percentage = 1.0 - minimum_free_percentage;
1050 const double maximum_free_percentage = (double) MaxHeapFreeRatio / 100; 1054 const double maximum_free_percentage = (double) MaxHeapFreeRatio / 100.0;
1051 const double minimum_used_percentage = 1.0 - maximum_free_percentage; 1055 const double minimum_used_percentage = 1.0 - maximum_free_percentage;
1052 1056
1053 size_t minimum_desired_capacity = (size_t) (used_after_gc / maximum_used_percentage); 1057 const size_t min_heap_size = collector_policy()->min_heap_byte_size();
1054 size_t maximum_desired_capacity = (size_t) (used_after_gc / minimum_used_percentage); 1058 const size_t max_heap_size = collector_policy()->max_heap_byte_size();
1055 1059
1056 // Don't shrink less than the initial size. 1060 // We have to be careful here as these two calculations can overflow
1057 minimum_desired_capacity = 1061 // 32-bit size_t's.
1058 MAX2(minimum_desired_capacity, 1062 double used_after_gc_d = (double) used_after_gc;
1059 collector_policy()->initial_heap_byte_size()); 1063 double minimum_desired_capacity_d = used_after_gc_d / maximum_used_percentage;
1060 maximum_desired_capacity = 1064 double maximum_desired_capacity_d = used_after_gc_d / minimum_used_percentage;
1061 MAX2(maximum_desired_capacity, 1065
1062 collector_policy()->initial_heap_byte_size()); 1066 // Let's make sure that they are both under the max heap size, which
1063 1067 // by default will make them fit into a size_t.
1064 // We are failing here because minimum_desired_capacity is 1068 double desired_capacity_upper_bound = (double) max_heap_size;
1065 assert(used_after_gc <= minimum_desired_capacity, "sanity check"); 1069 minimum_desired_capacity_d = MIN2(minimum_desired_capacity_d,
1066 assert(minimum_desired_capacity <= maximum_desired_capacity, "sanity check"); 1070 desired_capacity_upper_bound);
1071 maximum_desired_capacity_d = MIN2(maximum_desired_capacity_d,
1072 desired_capacity_upper_bound);
1073
1074 // We can now safely turn them into size_t's.
1075 size_t minimum_desired_capacity = (size_t) minimum_desired_capacity_d;
1076 size_t maximum_desired_capacity = (size_t) maximum_desired_capacity_d;
1077
1078 // This assert only makes sense here, before we adjust them
1079 // with respect to the min and max heap size.
1080 assert(minimum_desired_capacity <= maximum_desired_capacity,
1081 err_msg("minimum_desired_capacity = "SIZE_FORMAT", "
1082 "maximum_desired_capacity = "SIZE_FORMAT,
1083 minimum_desired_capacity, maximum_desired_capacity));
1084
1085 // Should not be greater than the heap max size. No need to adjust
1086 // it with respect to the heap min size as it's a lower bound (i.e.,
1087 // we'll try to make the capacity larger than it, not smaller).
1088 minimum_desired_capacity = MIN2(minimum_desired_capacity, max_heap_size);
1089 // Should not be less than the heap min size. No need to adjust it
1090 // with respect to the heap max size as it's an upper bound (i.e.,
1091 // we'll try to make the capacity smaller than it, not greater).
1092 maximum_desired_capacity = MAX2(maximum_desired_capacity, min_heap_size);
1067 1093
1068 if (PrintGC && Verbose) { 1094 if (PrintGC && Verbose) {
1069 const double free_percentage = ((double)free_after_gc) / capacity(); 1095 const double free_percentage =
1096 (double) free_after_gc / (double) capacity_after_gc;
1070 gclog_or_tty->print_cr("Computing new size after full GC "); 1097 gclog_or_tty->print_cr("Computing new size after full GC ");
1071 gclog_or_tty->print_cr(" " 1098 gclog_or_tty->print_cr(" "
1072 " minimum_free_percentage: %6.2f", 1099 " minimum_free_percentage: %6.2f",
1073 minimum_free_percentage); 1100 minimum_free_percentage);
1074 gclog_or_tty->print_cr(" " 1101 gclog_or_tty->print_cr(" "
1076 maximum_free_percentage); 1103 maximum_free_percentage);
1077 gclog_or_tty->print_cr(" " 1104 gclog_or_tty->print_cr(" "
1078 " capacity: %6.1fK" 1105 " capacity: %6.1fK"
1079 " minimum_desired_capacity: %6.1fK" 1106 " minimum_desired_capacity: %6.1fK"
1080 " maximum_desired_capacity: %6.1fK", 1107 " maximum_desired_capacity: %6.1fK",
1081 capacity() / (double) K, 1108 (double) capacity_after_gc / (double) K,
1082 minimum_desired_capacity / (double) K, 1109 (double) minimum_desired_capacity / (double) K,
1083 maximum_desired_capacity / (double) K); 1110 (double) maximum_desired_capacity / (double) K);
1084 gclog_or_tty->print_cr(" " 1111 gclog_or_tty->print_cr(" "
1085 " free_after_gc : %6.1fK" 1112 " free_after_gc: %6.1fK"
1086 " used_after_gc : %6.1fK", 1113 " used_after_gc: %6.1fK",
1087 free_after_gc / (double) K, 1114 (double) free_after_gc / (double) K,
1088 used_after_gc / (double) K); 1115 (double) used_after_gc / (double) K);
1089 gclog_or_tty->print_cr(" " 1116 gclog_or_tty->print_cr(" "
1090 " free_percentage: %6.2f", 1117 " free_percentage: %6.2f",
1091 free_percentage); 1118 free_percentage);
1092 } 1119 }
1093 if (capacity() < minimum_desired_capacity) { 1120 if (capacity_after_gc < minimum_desired_capacity) {
1094 // Don't expand unless it's significant 1121 // Don't expand unless it's significant
1095 size_t expand_bytes = minimum_desired_capacity - capacity_after_gc; 1122 size_t expand_bytes = minimum_desired_capacity - capacity_after_gc;
1096 expand(expand_bytes); 1123 expand(expand_bytes);
1097 if (PrintGC && Verbose) { 1124 if (PrintGC && Verbose) {
1098 gclog_or_tty->print_cr(" expanding:" 1125 gclog_or_tty->print_cr(" "
1126 " expanding:"
1127 " max_heap_size: %6.1fK"
1099 " minimum_desired_capacity: %6.1fK" 1128 " minimum_desired_capacity: %6.1fK"
1100 " expand_bytes: %6.1fK", 1129 " expand_bytes: %6.1fK",
1101 minimum_desired_capacity / (double) K, 1130 (double) max_heap_size / (double) K,
1102 expand_bytes / (double) K); 1131 (double) minimum_desired_capacity / (double) K,
1132 (double) expand_bytes / (double) K);
1103 } 1133 }
1104 1134
1105 // No expansion, now see if we want to shrink 1135 // No expansion, now see if we want to shrink
1106 } else if (capacity() > maximum_desired_capacity) { 1136 } else if (capacity_after_gc > maximum_desired_capacity) {
1107 // Capacity too large, compute shrinking size 1137 // Capacity too large, compute shrinking size
1108 size_t shrink_bytes = capacity_after_gc - maximum_desired_capacity; 1138 size_t shrink_bytes = capacity_after_gc - maximum_desired_capacity;
1109 shrink(shrink_bytes); 1139 shrink(shrink_bytes);
1110 if (PrintGC && Verbose) { 1140 if (PrintGC && Verbose) {
1111 gclog_or_tty->print_cr(" " 1141 gclog_or_tty->print_cr(" "
1112 " shrinking:" 1142 " shrinking:"
1113 " initSize: %.1fK" 1143 " min_heap_size: %6.1fK"
1114 " maximum_desired_capacity: %.1fK", 1144 " maximum_desired_capacity: %6.1fK"
1115 collector_policy()->initial_heap_byte_size() / (double) K, 1145 " shrink_bytes: %6.1fK",
1116 maximum_desired_capacity / (double) K); 1146 (double) min_heap_size / (double) K,
1117 gclog_or_tty->print_cr(" " 1147 (double) maximum_desired_capacity / (double) K,
1118 " shrink_bytes: %.1fK", 1148 (double) shrink_bytes / (double) K);
1119 shrink_bytes / (double) K);
1120 } 1149 }
1121 } 1150 }
1122 } 1151 }
1123 1152
1124 1153