Print this page
JDK-8236073 G1: Use SoftMaxHeapSize to guide GC heuristics

Split Close
Expand all
Collapse all
          --- old/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
          +++ new/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
↓ open down ↓ 1052 lines elided ↑ open up ↑
1053 1053    hrm()->prepare_for_full_collection_end();
1054 1054  
1055 1055    // Delete metaspaces for unloaded class loaders and clean up loader_data graph
1056 1056    ClassLoaderDataGraph::purge();
1057 1057    MetaspaceUtils::verify_metrics();
1058 1058  
1059 1059    // Prepare heap for normal collections.
1060 1060    assert(num_free_regions() == 0, "we should not have added any free regions");
1061 1061    rebuild_region_sets(false /* free_list_only */);
1062 1062    abort_refinement();
1063      -  resize_heap_if_necessary();
     1063 +
     1064 +  resize_heap_after_full_gc();
1064 1065  
1065 1066    // Rebuild the strong code root lists for each region
1066 1067    rebuild_strong_code_roots();
1067 1068  
1068 1069    // Purge code root memory
1069 1070    purge_code_root_memory();
1070 1071  
1071 1072    // Start a new incremental collection set for the next pause
1072 1073    start_new_collection_set();
1073 1074  
↓ open down ↓ 86 lines elided ↑ open up ↑
1160 1161  }
1161 1162  
1162 1163  void G1CollectedHeap::do_full_collection(bool clear_all_soft_refs) {
1163 1164    // Currently, there is no facility in the do_full_collection(bool) API to notify
1164 1165    // the caller that the collection did not succeed (e.g., because it was locked
1165 1166    // out by the GC locker). So, right now, we'll ignore the return value.
1166 1167    bool dummy = do_full_collection(true,                /* explicit_gc */
1167 1168                                    clear_all_soft_refs);
1168 1169  }
1169 1170  
1170      -void G1CollectedHeap::resize_heap_if_necessary() {
     1171 +void G1CollectedHeap::resize_heap_after_full_gc() {
1171 1172    assert_at_safepoint_on_vm_thread();
     1173 +  assert(collector_state()->in_full_gc(), "Must be");
1172 1174  
1173 1175    // Capacity, free and used after the GC counted as full regions to
1174 1176    // include the waste in the following calculations.
1175 1177    const size_t capacity_after_gc = capacity();
1176 1178    const size_t used_after_gc = capacity_after_gc - unused_committed_regions_in_bytes();
1177 1179  
1178      -  // This is enforced in arguments.cpp.
1179      -  assert(MinHeapFreeRatio <= MaxHeapFreeRatio,
1180      -         "otherwise the code below doesn't make sense");
1181      -
1182      -  // We don't have floating point command-line arguments
1183      -  const double minimum_free_percentage = (double) MinHeapFreeRatio / 100.0;
1184      -  const double maximum_used_percentage = 1.0 - minimum_free_percentage;
1185      -  const double maximum_free_percentage = (double) MaxHeapFreeRatio / 100.0;
1186      -  const double minimum_used_percentage = 1.0 - maximum_free_percentage;
1187      -
1188      -  // We have to be careful here as these two calculations can overflow
1189      -  // 32-bit size_t's.
1190      -  double used_after_gc_d = (double) used_after_gc;
1191      -  double minimum_desired_capacity_d = used_after_gc_d / maximum_used_percentage;
1192      -  double maximum_desired_capacity_d = used_after_gc_d / minimum_used_percentage;
1193      -
1194      -  // Let's make sure that they are both under the max heap size, which
1195      -  // by default will make them fit into a size_t.
1196      -  double desired_capacity_upper_bound = (double) MaxHeapSize;
1197      -  minimum_desired_capacity_d = MIN2(minimum_desired_capacity_d,
1198      -                                    desired_capacity_upper_bound);
1199      -  maximum_desired_capacity_d = MIN2(maximum_desired_capacity_d,
1200      -                                    desired_capacity_upper_bound);
1201      -
1202      -  // We can now safely turn them into size_t's.
1203      -  size_t minimum_desired_capacity = (size_t) minimum_desired_capacity_d;
1204      -  size_t maximum_desired_capacity = (size_t) maximum_desired_capacity_d;
     1180 +  size_t minimum_desired_capacity = _heap_sizing_policy->target_heap_capacity(used_after_gc, MinHeapFreeRatio);
     1181 +  size_t maximum_desired_capacity = _heap_sizing_policy->target_heap_capacity(used_after_gc, MaxHeapFreeRatio);
1205 1182  
1206 1183    // This assert only makes sense here, before we adjust them
1207 1184    // with respect to the min and max heap size.
1208 1185    assert(minimum_desired_capacity <= maximum_desired_capacity,
1209 1186           "minimum_desired_capacity = " SIZE_FORMAT ", "
1210 1187           "maximum_desired_capacity = " SIZE_FORMAT,
1211 1188           minimum_desired_capacity, maximum_desired_capacity);
1212 1189  
1213 1190    // Should not be greater than the heap max size. No need to adjust
1214 1191    // it with respect to the heap min size as it's a lower bound (i.e.,
↓ open down ↓ 1204 lines elided ↑ open up ↑
2419 2396  }
2420 2397  
2421 2398  size_t G1CollectedHeap::max_capacity() const {
2422 2399    return _hrm->max_expandable_length() * HeapRegion::GrainBytes;
2423 2400  }
2424 2401  
2425 2402  size_t G1CollectedHeap::max_reserved_capacity() const {
2426 2403    return _hrm->max_length() * HeapRegion::GrainBytes;
2427 2404  }
2428 2405  
     2406 +size_t G1CollectedHeap::soft_max_capacity() const {
     2407 +  return clamp(align_up(SoftMaxHeapSize, HeapAlignment), MinHeapSize, max_capacity());
     2408 +}
     2409 +
2429 2410  jlong G1CollectedHeap::millis_since_last_gc() {
2430 2411    // See the notes in GenCollectedHeap::millis_since_last_gc()
2431 2412    // for more information about the implementation.
2432 2413    jlong ret_val = (os::javaTimeNanos() / NANOSECS_PER_MILLISEC) -
2433 2414                    _policy->collection_pause_end_millis();
2434 2415    if (ret_val < 0) {
2435 2416      log_warning(gc)("millis_since_last_gc() would return : " JLONG_FORMAT
2436 2417        ". returning zero instead.", ret_val);
2437 2418      return 0;
2438 2419    }
↓ open down ↓ 506 lines elided ↑ open up ↑
2945 2926    if (VerifyRememberedSets) {
2946 2927      log_info(gc, verify)("[Verifying RemSets after GC]");
2947 2928      VerifyRegionRemSetClosure v_cl;
2948 2929      heap_region_iterate(&v_cl);
2949 2930    }
2950 2931    _verifier->verify_after_gc(type);
2951 2932    _verifier->check_bitmaps("GC End");
2952 2933    verify_numa_regions("GC End");
2953 2934  }
2954 2935  
2955      -void G1CollectedHeap::expand_heap_after_young_collection(){
2956      -  size_t expand_bytes = _heap_sizing_policy->expansion_amount();
     2936 +void G1CollectedHeap::resize_heap_after_young_collection() {
     2937 +  Ticks start = Ticks::now();
     2938 +  if (!expand_heap_after_young_collection()) {
     2939 +    // If we don't attempt to expand heap, try if we need to shrink the heap
     2940 +    shrink_heap_after_young_collection();
     2941 +  }
     2942 +  phase_times()->record_resize_heap_time((Ticks::now() - start).seconds() * 1000.0);
     2943 +}
     2944 +
     2945 +bool G1CollectedHeap::expand_heap_after_young_collection(){
     2946 +  size_t expand_bytes = _heap_sizing_policy->expansion_amount_after_young_collection();
2957 2947    if (expand_bytes > 0) {
2958      -    // No need for an ergo logging here,
2959      -    // expansion_amount() does this when it returns a value > 0.
2960      -    double expand_ms;
2961      -    if (!expand(expand_bytes, _workers, &expand_ms)) {
     2948 +    if (expand(expand_bytes, _workers, NULL)) {
2962 2949        // We failed to expand the heap. Cannot do anything about it.
2963 2950      }
2964      -    phase_times()->record_expand_heap_time(expand_ms);
     2951 +    return true;
     2952 +  }
     2953 +  return false;
     2954 +}
     2955 +
     2956 +void G1CollectedHeap::shrink_heap_after_young_collection() {
     2957 +  if (collector_state()->in_young_only_phase() || policy()->next_gc_should_be_mixed()) {
     2958 +    // Do the shrink during gc only at the end of mixed gc phase
     2959 +    return;
     2960 +  }
     2961 +  size_t shrink_bytes = _heap_sizing_policy->shrink_amount_at_last_mixed_gc(policy()->desired_bytes_after_concurrent_mark());
     2962 +  if (shrink_bytes > 0) {
     2963 +    shrink(shrink_bytes);
     2964 +  }
     2965 +}
     2966 +
     2967 +void G1CollectedHeap::shrink_heap_after_concurrent_mark() {
     2968 +  size_t shrink_bytes = _heap_sizing_policy->shrink_amount_after_concurrent_mark();
     2969 +  if (shrink_bytes > 0) {
     2970 +    shrink(shrink_bytes);
2965 2971    }
2966 2972  }
2967 2973  
2968 2974  const char* G1CollectedHeap::young_gc_name() const {
2969 2975    if (collector_state()->in_initial_mark_gc()) {
2970 2976      return "Pause Young (Concurrent Start)";
2971 2977    } else if (collector_state()->in_young_only_phase()) {
2972 2978      if (collector_state()->in_young_gc_before_mixed()) {
2973 2979        return "Pause Young (Prepare Mixed)";
2974 2980      } else {
↓ open down ↓ 135 lines elided ↑ open up ↑
3110 3116            concurrent_mark()->post_initial_mark();
3111 3117            // Note that we don't actually trigger the CM thread at
3112 3118            // this point. We do that later when we're sure that
3113 3119            // the current thread has completed its logging output.
3114 3120          }
3115 3121  
3116 3122          allocate_dummy_regions();
3117 3123  
3118 3124          _allocator->init_mutator_alloc_regions();
3119 3125  
3120      -        expand_heap_after_young_collection();
     3126 +        resize_heap_after_young_collection();
3121 3127  
3122 3128          double sample_end_time_sec = os::elapsedTime();
3123 3129          double pause_time_ms = (sample_end_time_sec - sample_start_time_sec) * MILLIUNITS;
3124 3130          policy()->record_collection_pause_end(pause_time_ms);
3125 3131        }
3126 3132  
3127 3133        verify_after_young_collection(verify_type);
3128 3134  
3129 3135  #ifdef TRACESPINNING
3130 3136        ParallelTaskTerminator::print_termination_counts();
↓ open down ↓ 1853 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX