1022 double* data) { |
1022 double* data) { |
1023 double min = data[0], max = data[0]; |
1023 double min = data[0], max = data[0]; |
1024 double total = 0.0; |
1024 double total = 0.0; |
1025 LineBuffer buf(level); |
1025 LineBuffer buf(level); |
1026 buf.append("[%s (ms):", str); |
1026 buf.append("[%s (ms):", str); |
1027 for (uint i = 0; i < ParallelGCThreads; ++i) { |
1027 for (uint i = 0; i < no_of_gc_threads(); ++i) { |
1028 double val = data[i]; |
1028 double val = data[i]; |
1029 if (val < min) |
1029 if (val < min) |
1030 min = val; |
1030 min = val; |
1031 if (val > max) |
1031 if (val > max) |
1032 max = val; |
1032 max = val; |
1033 total += val; |
1033 total += val; |
1034 buf.append(" %3.1lf", val); |
1034 buf.append(" %3.1lf", val); |
1035 } |
1035 } |
1036 buf.append_and_print_cr(""); |
1036 buf.append_and_print_cr(""); |
1037 double avg = total / (double) ParallelGCThreads; |
1037 double avg = total / (double) no_of_gc_threads(); |
1038 buf.append_and_print_cr(" Avg: %5.1lf, Min: %5.1lf, Max: %5.1lf, Diff: %5.1lf]", |
1038 buf.append_and_print_cr(" Avg: %5.1lf, Min: %5.1lf, Max: %5.1lf, Diff: %5.1lf]", |
1039 avg, min, max, max - min); |
1039 avg, min, max, max - min); |
1040 } |
1040 } |
1041 |
1041 |
1042 void G1CollectorPolicy::print_par_sizes(int level, |
1042 void G1CollectorPolicy::print_par_sizes(int level, |
1044 double* data) { |
1044 double* data) { |
1045 double min = data[0], max = data[0]; |
1045 double min = data[0], max = data[0]; |
1046 double total = 0.0; |
1046 double total = 0.0; |
1047 LineBuffer buf(level); |
1047 LineBuffer buf(level); |
1048 buf.append("[%s :", str); |
1048 buf.append("[%s :", str); |
1049 for (uint i = 0; i < ParallelGCThreads; ++i) { |
1049 for (uint i = 0; i < no_of_gc_threads(); ++i) { |
1050 double val = data[i]; |
1050 double val = data[i]; |
1051 if (val < min) |
1051 if (val < min) |
1052 min = val; |
1052 min = val; |
1053 if (val > max) |
1053 if (val > max) |
1054 max = val; |
1054 max = val; |
1055 total += val; |
1055 total += val; |
1056 buf.append(" %d", (int) val); |
1056 buf.append(" %d", (int) val); |
1057 } |
1057 } |
1058 buf.append_and_print_cr(""); |
1058 buf.append_and_print_cr(""); |
1059 double avg = total / (double) ParallelGCThreads; |
1059 double avg = total / (double) no_of_gc_threads(); |
1060 buf.append_and_print_cr(" Sum: %d, Avg: %d, Min: %d, Max: %d, Diff: %d]", |
1060 buf.append_and_print_cr(" Sum: %d, Avg: %d, Min: %d, Max: %d, Diff: %d]", |
1061 (int)total, (int)avg, (int)min, (int)max, (int)max - (int)min); |
1061 (int)total, (int)avg, (int)min, (int)max, (int)max - (int)min); |
1062 } |
1062 } |
1063 |
1063 |
1064 void G1CollectorPolicy::print_stats(int level, |
1064 void G1CollectorPolicy::print_stats(int level, |
1074 } |
1074 } |
1075 |
1075 |
1076 double G1CollectorPolicy::avg_value(double* data) { |
1076 double G1CollectorPolicy::avg_value(double* data) { |
1077 if (G1CollectedHeap::use_parallel_gc_threads()) { |
1077 if (G1CollectedHeap::use_parallel_gc_threads()) { |
1078 double ret = 0.0; |
1078 double ret = 0.0; |
1079 for (uint i = 0; i < ParallelGCThreads; ++i) { |
1079 for (uint i = 0; i < no_of_gc_threads(); ++i) { |
1080 ret += data[i]; |
1080 ret += data[i]; |
1081 } |
1081 } |
1082 return ret / (double) ParallelGCThreads; |
1082 return ret / (double) no_of_gc_threads(); |
1083 } else { |
1083 } else { |
1084 return data[0]; |
1084 return data[0]; |
1085 } |
1085 } |
1086 } |
1086 } |
1087 |
1087 |
1088 double G1CollectorPolicy::max_value(double* data) { |
1088 double G1CollectorPolicy::max_value(double* data) { |
1089 if (G1CollectedHeap::use_parallel_gc_threads()) { |
1089 if (G1CollectedHeap::use_parallel_gc_threads()) { |
1090 double ret = data[0]; |
1090 double ret = data[0]; |
1091 for (uint i = 1; i < ParallelGCThreads; ++i) { |
1091 for (uint i = 1; i < no_of_gc_threads(); ++i) { |
1092 if (data[i] > ret) { |
1092 if (data[i] > ret) { |
1093 ret = data[i]; |
1093 ret = data[i]; |
1094 } |
1094 } |
1095 } |
1095 } |
1096 return ret; |
1096 return ret; |
1113 |
1113 |
1114 double G1CollectorPolicy::max_sum(double* data1, double* data2) { |
1114 double G1CollectorPolicy::max_sum(double* data1, double* data2) { |
1115 double ret = data1[0] + data2[0]; |
1115 double ret = data1[0] + data2[0]; |
1116 |
1116 |
1117 if (G1CollectedHeap::use_parallel_gc_threads()) { |
1117 if (G1CollectedHeap::use_parallel_gc_threads()) { |
1118 for (uint i = 1; i < ParallelGCThreads; ++i) { |
1118 for (uint i = 1; i < no_of_gc_threads(); ++i) { |
1119 double data = data1[i] + data2[i]; |
1119 double data = data1[i] + data2[i]; |
1120 if (data > ret) { |
1120 if (data > ret) { |
1121 ret = data; |
1121 ret = data; |
1122 } |
1122 } |
1123 } |
1123 } |
1126 } |
1126 } |
1127 |
1127 |
1128 // Anything below that is considered to be zero |
1128 // Anything below that is considered to be zero |
1129 #define MIN_TIMER_GRANULARITY 0.0000001 |
1129 #define MIN_TIMER_GRANULARITY 0.0000001 |
1130 |
1130 |
1131 void G1CollectorPolicy::record_collection_pause_end() { |
1131 void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) { |
1132 double end_time_sec = os::elapsedTime(); |
1132 double end_time_sec = os::elapsedTime(); |
1133 double elapsed_ms = _last_pause_time_ms; |
1133 double elapsed_ms = _last_pause_time_ms; |
1134 bool parallel = G1CollectedHeap::use_parallel_gc_threads(); |
1134 bool parallel = G1CollectedHeap::use_parallel_gc_threads(); |
1135 assert(_cur_collection_pause_used_regions_at_start >= cset_region_length(), |
1135 assert(_cur_collection_pause_used_regions_at_start >= cset_region_length(), |
1136 "otherwise, the subtraction below does not make sense"); |
1136 "otherwise, the subtraction below does not make sense"); |
1138 _cur_collection_pause_used_regions_at_start - cset_region_length(); |
1138 _cur_collection_pause_used_regions_at_start - cset_region_length(); |
1139 size_t cur_used_bytes = _g1->used(); |
1139 size_t cur_used_bytes = _g1->used(); |
1140 assert(cur_used_bytes == _g1->recalculate_used(), "It should!"); |
1140 assert(cur_used_bytes == _g1->recalculate_used(), "It should!"); |
1141 bool last_pause_included_initial_mark = false; |
1141 bool last_pause_included_initial_mark = false; |
1142 bool update_stats = !_g1->evacuation_failed(); |
1142 bool update_stats = !_g1->evacuation_failed(); |
|
1143 set_no_of_gc_threads(no_of_gc_threads); |
1143 |
1144 |
1144 #ifndef PRODUCT |
1145 #ifndef PRODUCT |
1145 if (G1YoungSurvRateVerbose) { |
1146 if (G1YoungSurvRateVerbose) { |
1146 gclog_or_tty->print_cr(""); |
1147 gclog_or_tty->print_cr(""); |
1147 _short_lived_surv_rate_group->print(); |
1148 _short_lived_surv_rate_group->print(); |
2302 |
2303 |
2303 void work(int i) { |
2304 void work(int i) { |
2304 ParKnownGarbageHRClosure parKnownGarbageCl(_hrSorted, _chunk_size, i); |
2305 ParKnownGarbageHRClosure parKnownGarbageCl(_hrSorted, _chunk_size, i); |
2305 // Back to zero for the claim value. |
2306 // Back to zero for the claim value. |
2306 _g1->heap_region_par_iterate_chunked(&parKnownGarbageCl, i, |
2307 _g1->heap_region_par_iterate_chunked(&parKnownGarbageCl, i, |
|
2308 _g1->workers()->active_workers(), |
2307 HeapRegion::InitialClaimValue); |
2309 HeapRegion::InitialClaimValue); |
2308 jint regions_added = parKnownGarbageCl.marked_regions_added(); |
2310 jint regions_added = parKnownGarbageCl.marked_regions_added(); |
2309 _hrSorted->incNumMarkedHeapRegions(regions_added); |
2311 _hrSorted->incNumMarkedHeapRegions(regions_added); |
2310 if (G1PrintParCleanupStats) { |
2312 if (G1PrintParCleanupStats) { |
2311 gclog_or_tty->print_cr(" Thread %d called %d times, added %d regions to list.", |
2313 gclog_or_tty->print_cr(" Thread %d called %d times, added %d regions to list.", |
2329 (clear_marked_end_sec - start_sec) * 1000.0); |
2331 (clear_marked_end_sec - start_sec) * 1000.0); |
2330 } |
2332 } |
2331 |
2333 |
2332 if (G1CollectedHeap::use_parallel_gc_threads()) { |
2334 if (G1CollectedHeap::use_parallel_gc_threads()) { |
2333 const size_t OverpartitionFactor = 4; |
2335 const size_t OverpartitionFactor = 4; |
2334 const size_t MinWorkUnit = 8; |
2336 size_t WorkUnit; |
2335 const size_t WorkUnit = |
2337 // The use of MinChunkSize = 8 in the original code |
2336 MAX2(_g1->n_regions() / (ParallelGCThreads * OverpartitionFactor), |
2338 // causes some assertion failures when the total number of |
2337 MinWorkUnit); |
2339 // region is less than 8. The code here tries to fix that. |
|
2340 // Should the original code also be fixed? |
|
2341 if (no_of_gc_threads > 0) { |
|
2342 const size_t MinWorkUnit = |
|
2343 MAX2(_g1->n_regions() / no_of_gc_threads, (size_t) 1U); |
|
2344 WorkUnit = |
|
2345 MAX2(_g1->n_regions() / (no_of_gc_threads * OverpartitionFactor), |
|
2346 MinWorkUnit); |
|
2347 } else { |
|
2348 assert(no_of_gc_threads > 0, |
|
2349 "The active gc workers should be greater than 0"); |
|
2350 // In a product build do something reasonable to avoid a crash. |
|
2351 const size_t MinWorkUnit = |
|
2352 MAX2(_g1->n_regions() / ParallelGCThreads, (size_t) 1U); |
|
2353 WorkUnit = |
|
2354 MAX2(_g1->n_regions() / (ParallelGCThreads * OverpartitionFactor), |
|
2355 MinWorkUnit); |
|
2356 } |
2338 _collectionSetChooser->prepareForAddMarkedHeapRegionsPar(_g1->n_regions(), |
2357 _collectionSetChooser->prepareForAddMarkedHeapRegionsPar(_g1->n_regions(), |
2339 WorkUnit); |
2358 WorkUnit); |
2340 ParKnownGarbageTask parKnownGarbageTask(_collectionSetChooser, |
2359 ParKnownGarbageTask parKnownGarbageTask(_collectionSetChooser, |
2341 (int) WorkUnit); |
2360 (int) WorkUnit); |
2342 _g1->workers()->run_task(&parKnownGarbageTask); |
2361 _g1->workers()->run_task(&parKnownGarbageTask); |