Print this page
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 ↓ 2418 lines elided ↑ open up ↑
2419 2419  }
2420 2420  
2421 2421  size_t G1CollectedHeap::max_capacity() const {
2422 2422    return _hrm->max_expandable_length() * HeapRegion::GrainBytes;
2423 2423  }
2424 2424  
2425 2425  size_t G1CollectedHeap::max_reserved_capacity() const {
2426 2426    return _hrm->max_length() * HeapRegion::GrainBytes;
2427 2427  }
2428 2428  
     2429 +size_t G1CollectedHeap::soft_max_capacity() const {
     2430 +  return clamp(align_up(SoftMaxHeapSize, HeapAlignment), MinHeapSize, max_capacity());
     2431 +}
     2432 +
2429 2433  jlong G1CollectedHeap::millis_since_last_gc() {
2430 2434    // See the notes in GenCollectedHeap::millis_since_last_gc()
2431 2435    // for more information about the implementation.
2432 2436    jlong ret_val = (os::javaTimeNanos() / NANOSECS_PER_MILLISEC) -
2433 2437                    _policy->collection_pause_end_millis();
2434 2438    if (ret_val < 0) {
2435 2439      log_warning(gc)("millis_since_last_gc() would return : " JLONG_FORMAT
2436 2440        ". returning zero instead.", ret_val);
2437 2441      return 0;
2438 2442    }
↓ open down ↓ 506 lines elided ↑ open up ↑
2945 2949    if (VerifyRememberedSets) {
2946 2950      log_info(gc, verify)("[Verifying RemSets after GC]");
2947 2951      VerifyRegionRemSetClosure v_cl;
2948 2952      heap_region_iterate(&v_cl);
2949 2953    }
2950 2954    _verifier->verify_after_gc(type);
2951 2955    _verifier->check_bitmaps("GC End");
2952 2956    verify_numa_regions("GC End");
2953 2957  }
2954 2958  
2955      -void G1CollectedHeap::expand_heap_after_young_collection(){
2956      -  size_t expand_bytes = _heap_sizing_policy->expansion_amount();
     2959 +void G1CollectedHeap::resize_heap_after_young_collection() {
     2960 +  Ticks start = Ticks::now();
     2961 +  if (!expand_heap_after_young_collection()) {
     2962 +    // If we don't attempt to expand heap, try if we need to shrink the heap
     2963 +    shrink_heap_after_young_collection();
     2964 +  }
     2965 +  phase_times()->record_resize_heap_time((Ticks::now() - start).seconds() * 1000.0);
     2966 +}
     2967 +
     2968 +bool G1CollectedHeap::expand_heap_after_young_collection(){
     2969 +  size_t expand_bytes = _heap_sizing_policy->expansion_amount_after_young_collection();
2957 2970    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)) {
     2971 +    if (expand(expand_bytes, _workers, NULL)) {
2962 2972        // We failed to expand the heap. Cannot do anything about it.
2963 2973      }
2964      -    phase_times()->record_expand_heap_time(expand_ms);
     2974 +    return true;
     2975 +  }
     2976 +  return false;
     2977 +}
     2978 +
     2979 +void G1CollectedHeap::shrink_heap_after_young_collection() {
     2980 +  if (!collector_state()->finish_of_mixed_gc()) {
     2981 +    // Do the shrink only after finish of mixed gc
     2982 +    return;
     2983 +  }
     2984 +  size_t shrink_bytes = _heap_sizing_policy->shrink_amount_after_mixed_collections();
     2985 +  if (shrink_bytes > 0) {
     2986 +    shrink(shrink_bytes);
     2987 +  }
     2988 +}
     2989 +
     2990 +void G1CollectedHeap::expand_heap_after_concurrent_mark() {
     2991 +  size_t expand_bytes = _heap_sizing_policy->expansion_amount_after_concurrent_mark();
     2992 +  if (expand_bytes > 0) {
     2993 +    expand(expand_bytes, _workers, NULL);
2965 2994    }
2966 2995  }
2967 2996  
2968 2997  const char* G1CollectedHeap::young_gc_name() const {
2969 2998    if (collector_state()->in_initial_mark_gc()) {
2970 2999      return "Pause Young (Concurrent Start)";
2971 3000    } else if (collector_state()->in_young_only_phase()) {
2972 3001      if (collector_state()->in_young_gc_before_mixed()) {
2973 3002        return "Pause Young (Prepare Mixed)";
2974 3003      } else {
↓ open down ↓ 135 lines elided ↑ open up ↑
3110 3139            concurrent_mark()->post_initial_mark();
3111 3140            // Note that we don't actually trigger the CM thread at
3112 3141            // this point. We do that later when we're sure that
3113 3142            // the current thread has completed its logging output.
3114 3143          }
3115 3144  
3116 3145          allocate_dummy_regions();
3117 3146  
3118 3147          _allocator->init_mutator_alloc_regions();
3119 3148  
3120      -        expand_heap_after_young_collection();
     3149 +        resize_heap_after_young_collection();
3121 3150  
3122 3151          double sample_end_time_sec = os::elapsedTime();
3123 3152          double pause_time_ms = (sample_end_time_sec - sample_start_time_sec) * MILLIUNITS;
3124 3153          policy()->record_collection_pause_end(pause_time_ms);
3125 3154        }
3126 3155  
3127 3156        verify_after_young_collection(verify_type);
3128 3157  
3129 3158  #ifdef TRACESPINNING
3130 3159        ParallelTaskTerminator::print_termination_counts();
↓ open down ↓ 1853 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX