src/hotspot/share/gc/g1/g1YoungGenSizer.cpp
changeset 47216 71c04702a3d5
parent 39961 49fb257108d6
child 51332 c25572739e7c
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  *
       
    23  */
       
    24 
       
    25 #include "precompiled.hpp"
       
    26 #include "gc/g1/g1YoungGenSizer.hpp"
       
    27 #include "gc/g1/heapRegion.hpp"
       
    28 #include "logging/log.hpp"
       
    29 
       
    30 G1YoungGenSizer::G1YoungGenSizer() : _sizer_kind(SizerDefaults), _adaptive_size(true),
       
    31         _min_desired_young_length(0), _max_desired_young_length(0) {
       
    32   if (FLAG_IS_CMDLINE(NewRatio)) {
       
    33     if (FLAG_IS_CMDLINE(NewSize) || FLAG_IS_CMDLINE(MaxNewSize)) {
       
    34       log_warning(gc, ergo)("-XX:NewSize and -XX:MaxNewSize override -XX:NewRatio");
       
    35     } else {
       
    36       _sizer_kind = SizerNewRatio;
       
    37       _adaptive_size = false;
       
    38       return;
       
    39     }
       
    40   }
       
    41 
       
    42   if (NewSize > MaxNewSize) {
       
    43     if (FLAG_IS_CMDLINE(MaxNewSize)) {
       
    44       log_warning(gc, ergo)("NewSize (" SIZE_FORMAT "k) is greater than the MaxNewSize (" SIZE_FORMAT "k). "
       
    45                             "A new max generation size of " SIZE_FORMAT "k will be used.",
       
    46                             NewSize/K, MaxNewSize/K, NewSize/K);
       
    47     }
       
    48     FLAG_SET_ERGO(size_t, MaxNewSize, NewSize);
       
    49   }
       
    50 
       
    51   if (FLAG_IS_CMDLINE(NewSize)) {
       
    52     _min_desired_young_length = MAX2((uint) (NewSize / HeapRegion::GrainBytes),
       
    53                                      1U);
       
    54     if (FLAG_IS_CMDLINE(MaxNewSize)) {
       
    55       _max_desired_young_length =
       
    56                              MAX2((uint) (MaxNewSize / HeapRegion::GrainBytes),
       
    57                                   1U);
       
    58       _sizer_kind = SizerMaxAndNewSize;
       
    59       _adaptive_size = _min_desired_young_length != _max_desired_young_length;
       
    60     } else {
       
    61       _sizer_kind = SizerNewSizeOnly;
       
    62     }
       
    63   } else if (FLAG_IS_CMDLINE(MaxNewSize)) {
       
    64     _max_desired_young_length =
       
    65                              MAX2((uint) (MaxNewSize / HeapRegion::GrainBytes),
       
    66                                   1U);
       
    67     _sizer_kind = SizerMaxNewSizeOnly;
       
    68   }
       
    69 }
       
    70 
       
    71 uint G1YoungGenSizer::calculate_default_min_length(uint new_number_of_heap_regions) {
       
    72   uint default_value = (new_number_of_heap_regions * G1NewSizePercent) / 100;
       
    73   return MAX2(1U, default_value);
       
    74 }
       
    75 
       
    76 uint G1YoungGenSizer::calculate_default_max_length(uint new_number_of_heap_regions) {
       
    77   uint default_value = (new_number_of_heap_regions * G1MaxNewSizePercent) / 100;
       
    78   return MAX2(1U, default_value);
       
    79 }
       
    80 
       
    81 void G1YoungGenSizer::recalculate_min_max_young_length(uint number_of_heap_regions, uint* min_young_length, uint* max_young_length) {
       
    82   assert(number_of_heap_regions > 0, "Heap must be initialized");
       
    83 
       
    84   switch (_sizer_kind) {
       
    85     case SizerDefaults:
       
    86       *min_young_length = calculate_default_min_length(number_of_heap_regions);
       
    87       *max_young_length = calculate_default_max_length(number_of_heap_regions);
       
    88       break;
       
    89     case SizerNewSizeOnly:
       
    90       *max_young_length = calculate_default_max_length(number_of_heap_regions);
       
    91       *max_young_length = MAX2(*min_young_length, *max_young_length);
       
    92       break;
       
    93     case SizerMaxNewSizeOnly:
       
    94       *min_young_length = calculate_default_min_length(number_of_heap_regions);
       
    95       *min_young_length = MIN2(*min_young_length, *max_young_length);
       
    96       break;
       
    97     case SizerMaxAndNewSize:
       
    98       // Do nothing. Values set on the command line, don't update them at runtime.
       
    99       break;
       
   100     case SizerNewRatio:
       
   101       *min_young_length = number_of_heap_regions / (NewRatio + 1);
       
   102       *max_young_length = *min_young_length;
       
   103       break;
       
   104     default:
       
   105       ShouldNotReachHere();
       
   106   }
       
   107 
       
   108   assert(*min_young_length <= *max_young_length, "Invalid min/max young gen size values");
       
   109 }
       
   110 
       
   111 void G1YoungGenSizer::adjust_max_new_size(uint number_of_heap_regions) {
       
   112 
       
   113   // We need to pass the desired values because recalculation may not update these
       
   114   // values in some cases.
       
   115   uint temp = _min_desired_young_length;
       
   116   uint result = _max_desired_young_length;
       
   117   recalculate_min_max_young_length(number_of_heap_regions, &temp, &result);
       
   118 
       
   119   size_t max_young_size = result * HeapRegion::GrainBytes;
       
   120   if (max_young_size != MaxNewSize) {
       
   121     FLAG_SET_ERGO(size_t, MaxNewSize, max_young_size);
       
   122   }
       
   123 }
       
   124 
       
   125 void G1YoungGenSizer::heap_size_changed(uint new_number_of_heap_regions) {
       
   126   recalculate_min_max_young_length(new_number_of_heap_regions, &_min_desired_young_length,
       
   127           &_max_desired_young_length);
       
   128 }