hotspot/src/share/vm/gc/g1/g1EvacStats.cpp
changeset 35061 be6025ebffea
parent 34230 b9c64b7c06c9
child 36390 a2d991d1d628
equal deleted inserted replaced
35060:382d0689141c 35061:be6025ebffea
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 #include "memory/allocation.inline.hpp"
    26 #include "memory/allocation.inline.hpp"
    27 #include "gc/g1/g1EvacStats.hpp"
    27 #include "gc/g1/g1EvacStats.hpp"
    28 #include "gc/shared/gcId.hpp"
    28 #include "gc/shared/gcId.hpp"
       
    29 #include "logging/log.hpp"
    29 #include "trace/tracing.hpp"
    30 #include "trace/tracing.hpp"
    30 
    31 
    31 void G1EvacStats::adjust_desired_plab_sz() {
    32 void G1EvacStats::adjust_desired_plab_sz() {
    32   if (PrintPLAB) {
    33   if (!ResizePLAB) {
    33     gclog_or_tty->print(" (allocated = " SIZE_FORMAT " wasted = " SIZE_FORMAT " "
    34     log_debug(gc, plab)(" (allocated = " SIZE_FORMAT " wasted = " SIZE_FORMAT " "
    34                         "unused = " SIZE_FORMAT " used = " SIZE_FORMAT " "
    35                         "unused = " SIZE_FORMAT " used = " SIZE_FORMAT " "
    35                         "undo_waste = " SIZE_FORMAT " region_end_waste = " SIZE_FORMAT " "
    36                         "undo_waste = " SIZE_FORMAT " region_end_waste = " SIZE_FORMAT " "
    36                         "regions filled = %u direct_allocated = " SIZE_FORMAT " "
    37                         "regions filled = %u direct_allocated = " SIZE_FORMAT " "
    37                         "failure_used = " SIZE_FORMAT " failure_waste = " SIZE_FORMAT ") ",
    38                         "failure_used = " SIZE_FORMAT " failure_waste = " SIZE_FORMAT ") ",
    38                         _allocated, _wasted, _unused, used(), _undo_wasted, _region_end_waste,
    39                         _allocated, _wasted, _unused, used(), _undo_wasted, _region_end_waste,
    39                         _regions_filled, _direct_allocated, _failure_used, _failure_waste);
    40                         _regions_filled, _direct_allocated, _failure_used, _failure_waste);
       
    41     // Clear accumulators for next round.
       
    42     reset();
       
    43     return;
    40   }
    44   }
    41 
    45 
    42   if (ResizePLAB) {
    46   assert(is_object_aligned(max_size()) && min_size() <= max_size(),
       
    47          "PLAB clipping computation may be incorrect");
    43 
    48 
    44     assert(is_object_aligned(max_size()) && min_size() <= max_size(),
    49   if (_allocated == 0) {
    45            "PLAB clipping computation may be incorrect");
    50     assert((_unused == 0),
       
    51            "Inconsistency in PLAB stats: "
       
    52            "_allocated: " SIZE_FORMAT ", "
       
    53            "_wasted: " SIZE_FORMAT ", "
       
    54            "_region_end_waste: " SIZE_FORMAT ", "
       
    55            "_unused: " SIZE_FORMAT ", "
       
    56            "_used  : " SIZE_FORMAT,
       
    57            _allocated, _wasted, _region_end_waste, _unused, used());
       
    58     _allocated = 1;
       
    59   }
       
    60   // The size of the PLAB caps the amount of space that can be wasted at the
       
    61   // end of the collection. In the worst case the last PLAB could be completely
       
    62   // empty.
       
    63   // This allows us to calculate the new PLAB size to achieve the
       
    64   // TargetPLABWastePct given the latest memory usage and that the last buffer
       
    65   // will be G1LastPLABAverageOccupancy full.
       
    66   //
       
    67   // E.g. assume that if in the current GC 100 words were allocated and a
       
    68   // TargetPLABWastePct of 10 had been set.
       
    69   //
       
    70   // So we could waste up to 10 words to meet that percentage. Given that we
       
    71   // also assume that that buffer is typically half-full, the new desired PLAB
       
    72   // size is set to 20 words.
       
    73   //
       
    74   // The amount of allocation performed should be independent of the number of
       
    75   // threads, so should the maximum waste we can spend in total. So if
       
    76   // we used n threads to allocate, each of them can spend maximum waste/n words in
       
    77   // a first rough approximation. The number of threads only comes into play later
       
    78   // when actually retrieving the actual desired PLAB size.
       
    79   //
       
    80   // After calculating this optimal PLAB size the algorithm applies the usual
       
    81   // exponential decaying average over this value to guess the next PLAB size.
       
    82   //
       
    83   // We account region end waste fully to PLAB allocation (in the calculation of
       
    84   // what we consider as "used_for_waste_calculation" below). This is not
       
    85   // completely fair, but is a conservative assumption because PLABs may be sized
       
    86   // flexibly while we cannot adjust inline allocations.
       
    87   // Allocation during GC will try to minimize region end waste so this impact
       
    88   // should be minimal.
       
    89   //
       
    90   // We need to cover overflow when calculating the amount of space actually used
       
    91   // by objects in PLABs when subtracting the region end waste.
       
    92   // Region end waste may be higher than actual allocation. This may occur if many
       
    93   // threads do not allocate anything but a few rather large objects. In this
       
    94   // degenerate case the PLAB size would simply quickly tend to minimum PLAB size,
       
    95   // which is an okay reaction.
       
    96   size_t const used_for_waste_calculation = used() > _region_end_waste ? used() - _region_end_waste : 0;
    46 
    97 
    47     if (_allocated == 0) {
    98   size_t const total_waste_allowed = used_for_waste_calculation * TargetPLABWastePct;
    48       assert((_unused == 0),
    99   size_t const cur_plab_sz = (size_t)((double)total_waste_allowed / G1LastPLABAverageOccupancy);
    49              "Inconsistency in PLAB stats: "
   100   // Take historical weighted average
    50              "_allocated: " SIZE_FORMAT ", "
   101   _filter.sample(cur_plab_sz);
    51              "_wasted: " SIZE_FORMAT ", "
   102   // Clip from above and below, and align to object boundary
    52              "_region_end_waste: " SIZE_FORMAT ", "
   103   size_t plab_sz;
    53              "_unused: " SIZE_FORMAT ", "
   104   plab_sz = MAX2(min_size(), (size_t)_filter.average());
    54              "_used  : " SIZE_FORMAT,
   105   plab_sz = MIN2(max_size(), plab_sz);
    55              _allocated, _wasted, _region_end_waste, _unused, used());
   106   plab_sz = align_object_size(plab_sz);
    56       _allocated = 1;
   107   // Latch the result
    57     }
   108   _desired_net_plab_sz = plab_sz;
    58     // The size of the PLAB caps the amount of space that can be wasted at the
       
    59     // end of the collection. In the worst case the last PLAB could be completely
       
    60     // empty.
       
    61     // This allows us to calculate the new PLAB size to achieve the
       
    62     // TargetPLABWastePct given the latest memory usage and that the last buffer
       
    63     // will be G1LastPLABAverageOccupancy full.
       
    64     //
       
    65     // E.g. assume that if in the current GC 100 words were allocated and a
       
    66     // TargetPLABWastePct of 10 had been set.
       
    67     //
       
    68     // So we could waste up to 10 words to meet that percentage. Given that we
       
    69     // also assume that that buffer is typically half-full, the new desired PLAB
       
    70     // size is set to 20 words.
       
    71     //
       
    72     // The amount of allocation performed should be independent of the number of
       
    73     // threads, so should the maximum waste we can spend in total. So if
       
    74     // we used n threads to allocate, each of them can spend maximum waste/n words in
       
    75     // a first rough approximation. The number of threads only comes into play later
       
    76     // when actually retrieving the actual desired PLAB size.
       
    77     //
       
    78     // After calculating this optimal PLAB size the algorithm applies the usual
       
    79     // exponential decaying average over this value to guess the next PLAB size.
       
    80     //
       
    81     // We account region end waste fully to PLAB allocation (in the calculation of
       
    82     // what we consider as "used_for_waste_calculation" below). This is not
       
    83     // completely fair, but is a conservative assumption because PLABs may be sized
       
    84     // flexibly while we cannot adjust inline allocations.
       
    85     // Allocation during GC will try to minimize region end waste so this impact
       
    86     // should be minimal.
       
    87     //
       
    88     // We need to cover overflow when calculating the amount of space actually used
       
    89     // by objects in PLABs when subtracting the region end waste.
       
    90     // Region end waste may be higher than actual allocation. This may occur if many
       
    91     // threads do not allocate anything but a few rather large objects. In this
       
    92     // degenerate case the PLAB size would simply quickly tend to minimum PLAB size,
       
    93     // which is an okay reaction.
       
    94     size_t const used_for_waste_calculation = used() > _region_end_waste ? used() - _region_end_waste : 0;
       
    95 
   109 
    96     size_t const total_waste_allowed = used_for_waste_calculation * TargetPLABWastePct;
   110   log_debug(gc, plab)(" (allocated = " SIZE_FORMAT " wasted = " SIZE_FORMAT " "
    97     size_t const cur_plab_sz = (size_t)((double)total_waste_allowed / G1LastPLABAverageOccupancy);
   111                       "unused = " SIZE_FORMAT " used = " SIZE_FORMAT " "
    98     // Take historical weighted average
   112                       "undo_waste = " SIZE_FORMAT " region_end_waste = " SIZE_FORMAT " "
    99     _filter.sample(cur_plab_sz);
   113                       "regions filled = %u direct_allocated = " SIZE_FORMAT " "
   100     // Clip from above and below, and align to object boundary
   114                       "failure_used = " SIZE_FORMAT " failure_waste = " SIZE_FORMAT ") "
   101     size_t plab_sz;
   115                       " (plab_sz = " SIZE_FORMAT " desired_plab_sz = " SIZE_FORMAT ")",
   102     plab_sz = MAX2(min_size(), (size_t)_filter.average());
   116                       _allocated, _wasted, _unused, used(), _undo_wasted, _region_end_waste,
   103     plab_sz = MIN2(max_size(), plab_sz);
   117                       _regions_filled, _direct_allocated, _failure_used, _failure_waste,
   104     plab_sz = align_object_size(plab_sz);
   118                       cur_plab_sz, plab_sz);
   105     // Latch the result
   119 
   106     _desired_net_plab_sz = plab_sz;
       
   107     if (PrintPLAB) {
       
   108       gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT " desired_plab_sz = " SIZE_FORMAT ") ", cur_plab_sz, plab_sz);
       
   109     }
       
   110   }
       
   111   if (PrintPLAB) {
       
   112     gclog_or_tty->cr();
       
   113   }
       
   114   // Clear accumulators for next round.
   120   // Clear accumulators for next round.
   115   reset();
   121   reset();
   116 }
   122 }
   117 
   123 
   118 G1EvacStats::~G1EvacStats() { }
   124 G1EvacStats::~G1EvacStats() { }