src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp

Mon, 07 Nov 2011 22:11:12 -0500

author
tonyp
date
Mon, 07 Nov 2011 22:11:12 -0500
changeset 3268
8aae2050e83e
parent 3176
8229bd737950
child 3620
b5290bf0a9e4
permissions
-rw-r--r--

7092309: G1: introduce old region set
Summary: Keep track of all the old regions in the heap with a heap region set.
Reviewed-by: brutisso, johnc

     1 /*
     2  * Copyright (c) 2011, 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  */
    25 #include "precompiled.hpp"
    26 #include "gc_implementation/g1/g1MonitoringSupport.hpp"
    27 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
    28 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
    30 G1GenerationCounters::G1GenerationCounters(G1MonitoringSupport* g1mm,
    31                                            const char* name,
    32                                            int ordinal, int spaces,
    33                                            size_t min_capacity,
    34                                            size_t max_capacity,
    35                                            size_t curr_capacity)
    36   : GenerationCounters(name, ordinal, spaces, min_capacity,
    37                        max_capacity, curr_capacity), _g1mm(g1mm) { }
    39 // We pad the capacity three times given that the young generation
    40 // contains three spaces (eden and two survivors).
    41 G1YoungGenerationCounters::G1YoungGenerationCounters(G1MonitoringSupport* g1mm,
    42                                                      const char* name)
    43   : G1GenerationCounters(g1mm, name, 0 /* ordinal */, 3 /* spaces */,
    44                G1MonitoringSupport::pad_capacity(0, 3) /* min_capacity */,
    45                G1MonitoringSupport::pad_capacity(g1mm->young_gen_max(), 3),
    46                G1MonitoringSupport::pad_capacity(0, 3) /* curr_capacity */) {
    47   update_all();
    48 }
    50 G1OldGenerationCounters::G1OldGenerationCounters(G1MonitoringSupport* g1mm,
    51                                                  const char* name)
    52   : G1GenerationCounters(g1mm, name, 1 /* ordinal */, 1 /* spaces */,
    53                G1MonitoringSupport::pad_capacity(0) /* min_capacity */,
    54                G1MonitoringSupport::pad_capacity(g1mm->old_gen_max()),
    55                G1MonitoringSupport::pad_capacity(0) /* curr_capacity */) {
    56   update_all();
    57 }
    59 void G1YoungGenerationCounters::update_all() {
    60   size_t committed =
    61             G1MonitoringSupport::pad_capacity(_g1mm->young_gen_committed(), 3);
    62   _current_size->set_value(committed);
    63 }
    65 void G1OldGenerationCounters::update_all() {
    66   size_t committed =
    67             G1MonitoringSupport::pad_capacity(_g1mm->old_gen_committed());
    68   _current_size->set_value(committed);
    69 }
    71 G1MonitoringSupport::G1MonitoringSupport(G1CollectedHeap* g1h) :
    72   _g1h(g1h),
    73   _incremental_collection_counters(NULL),
    74   _full_collection_counters(NULL),
    75   _old_collection_counters(NULL),
    76   _old_space_counters(NULL),
    77   _young_collection_counters(NULL),
    78   _eden_counters(NULL),
    79   _from_counters(NULL),
    80   _to_counters(NULL),
    82   _overall_reserved(0),
    83   _overall_committed(0),    _overall_used(0),
    84   _young_region_num(0),
    85   _young_gen_committed(0),
    86   _eden_committed(0),       _eden_used(0),
    87   _survivor_committed(0),   _survivor_used(0),
    88   _old_committed(0),        _old_used(0) {
    90   _overall_reserved = g1h->max_capacity();
    91   recalculate_sizes();
    93   // Counters for GC collections
    94   //
    95   //  name "collector.0".  In a generational collector this would be the
    96   // young generation collection.
    97   _incremental_collection_counters =
    98     new CollectorCounters("G1 incremental collections", 0);
    99   //   name "collector.1".  In a generational collector this would be the
   100   // old generation collection.
   101   _full_collection_counters =
   102     new CollectorCounters("G1 stop-the-world full collections", 1);
   104   // timer sampling for all counters supporting sampling only update the
   105   // used value.  See the take_sample() method.  G1 requires both used and
   106   // capacity updated so sampling is not currently used.  It might
   107   // be sufficient to update all counters in take_sample() even though
   108   // take_sample() only returns "used".  When sampling was used, there
   109   // were some anomolous values emitted which may have been the consequence
   110   // of not updating all values simultaneously (i.e., see the calculation done
   111   // in eden_space_used(), is it possbile that the values used to
   112   // calculate either eden_used or survivor_used are being updated by
   113   // the collector when the sample is being done?).
   114   const bool sampled = false;
   116   // "Generation" and "Space" counters.
   117   //
   118   //  name "generation.1" This is logically the old generation in
   119   // generational GC terms.  The "1, 1" parameters are for
   120   // the n-th generation (=1) with 1 space.
   121   // Counters are created from minCapacity, maxCapacity, and capacity
   122   _old_collection_counters = new G1OldGenerationCounters(this, "old");
   124   //  name  "generation.1.space.0"
   125   // Counters are created from maxCapacity, capacity, initCapacity,
   126   // and used.
   127   _old_space_counters = new HSpaceCounters("space", 0 /* ordinal */,
   128     pad_capacity(overall_reserved()) /* max_capacity */,
   129     pad_capacity(old_space_committed()) /* init_capacity */,
   130    _old_collection_counters);
   132   //   Young collection set
   133   //  name "generation.0".  This is logically the young generation.
   134   //  The "0, 3" are paremeters for the n-th genertaion (=0) with 3 spaces.
   135   // See  _old_collection_counters for additional counters
   136   _young_collection_counters = new G1YoungGenerationCounters(this, "young");
   138   //  name "generation.0.space.0"
   139   // See _old_space_counters for additional counters
   140   _eden_counters = new HSpaceCounters("eden", 0 /* ordinal */,
   141     pad_capacity(overall_reserved()) /* max_capacity */,
   142     pad_capacity(eden_space_committed()) /* init_capacity */,
   143     _young_collection_counters);
   145   //  name "generation.0.space.1"
   146   // See _old_space_counters for additional counters
   147   // Set the arguments to indicate that this survivor space is not used.
   148   _from_counters = new HSpaceCounters("s0", 1 /* ordinal */,
   149     pad_capacity(0) /* max_capacity */,
   150     pad_capacity(0) /* init_capacity */,
   151     _young_collection_counters);
   152   // Given that this survivor space is not used, we update it here
   153   // once to reflect that its used space is 0 so that we don't have to
   154   // worry about updating it again later.
   155   _from_counters->update_used(0);
   157   //  name "generation.0.space.2"
   158   // See _old_space_counters for additional counters
   159   _to_counters = new HSpaceCounters("s1", 2 /* ordinal */,
   160     pad_capacity(overall_reserved()) /* max_capacity */,
   161     pad_capacity(survivor_space_committed()) /* init_capacity */,
   162     _young_collection_counters);
   163 }
   165 void G1MonitoringSupport::recalculate_sizes() {
   166   G1CollectedHeap* g1 = g1h();
   168   // Recalculate all the sizes from scratch. We assume that this is
   169   // called at a point where no concurrent updates to the various
   170   // values we read here are possible (i.e., at a STW phase at the end
   171   // of a GC).
   173   size_t young_list_length = g1->young_list()->length();
   174   size_t survivor_list_length = g1->g1_policy()->recorded_survivor_regions();
   175   assert(young_list_length >= survivor_list_length, "invariant");
   176   size_t eden_list_length = young_list_length - survivor_list_length;
   177   // Max length includes any potential extensions to the young gen
   178   // we'll do when the GC locker is active.
   179   size_t young_list_max_length = g1->g1_policy()->young_list_max_length();
   180   assert(young_list_max_length >= survivor_list_length, "invariant");
   181   size_t eden_list_max_length = young_list_max_length - survivor_list_length;
   183   _overall_used = g1->used_unlocked();
   184   _eden_used = eden_list_length * HeapRegion::GrainBytes;
   185   _survivor_used = survivor_list_length * HeapRegion::GrainBytes;
   186   _young_region_num = young_list_length;
   187   _old_used = subtract_up_to_zero(_overall_used, _eden_used + _survivor_used);
   189   // First calculate the committed sizes that can be calculated independently.
   190   _survivor_committed = _survivor_used;
   191   _old_committed = HeapRegion::align_up_to_region_byte_size(_old_used);
   193   // Next, start with the overall committed size.
   194   _overall_committed = g1->capacity();
   195   size_t committed = _overall_committed;
   197   // Remove the committed size we have calculated so far (for the
   198   // survivor and old space).
   199   assert(committed >= (_survivor_committed + _old_committed), "sanity");
   200   committed -= _survivor_committed + _old_committed;
   202   // Next, calculate and remove the committed size for the eden.
   203   _eden_committed = eden_list_max_length * HeapRegion::GrainBytes;
   204   // Somewhat defensive: be robust in case there are inaccuracies in
   205   // the calculations
   206   _eden_committed = MIN2(_eden_committed, committed);
   207   committed -= _eden_committed;
   209   // Finally, give the rest to the old space...
   210   _old_committed += committed;
   211   // ..and calculate the young gen committed.
   212   _young_gen_committed = _eden_committed + _survivor_committed;
   214   assert(_overall_committed ==
   215          (_eden_committed + _survivor_committed + _old_committed),
   216          "the committed sizes should add up");
   217   // Somewhat defensive: cap the eden used size to make sure it
   218   // never exceeds the committed size.
   219   _eden_used = MIN2(_eden_used, _eden_committed);
   220   // _survivor_committed and _old_committed are calculated in terms of
   221   // the corresponding _*_used value, so the next two conditions
   222   // should hold.
   223   assert(_survivor_used <= _survivor_committed, "post-condition");
   224   assert(_old_used <= _old_committed, "post-condition");
   225 }
   227 void G1MonitoringSupport::recalculate_eden_size() {
   228   G1CollectedHeap* g1 = g1h();
   230   // When a new eden region is allocated, only the eden_used size is
   231   // affected (since we have recalculated everything else at the last GC).
   233   size_t young_region_num = g1h()->young_list()->length();
   234   if (young_region_num > _young_region_num) {
   235     size_t diff = young_region_num - _young_region_num;
   236     _eden_used += diff * HeapRegion::GrainBytes;
   237     // Somewhat defensive: cap the eden used size to make sure it
   238     // never exceeds the committed size.
   239     _eden_used = MIN2(_eden_used, _eden_committed);
   240     _young_region_num = young_region_num;
   241   }
   242 }
   244 void G1MonitoringSupport::update_sizes() {
   245   recalculate_sizes();
   246   if (UsePerfData) {
   247     eden_counters()->update_capacity(pad_capacity(eden_space_committed()));
   248     eden_counters()->update_used(eden_space_used());
   249     // only the to survivor space (s1) is active, so we don't need to
   250     // update the counteres for the from survivor space (s0)
   251     to_counters()->update_capacity(pad_capacity(survivor_space_committed()));
   252     to_counters()->update_used(survivor_space_used());
   253     old_space_counters()->update_capacity(pad_capacity(old_space_committed()));
   254     old_space_counters()->update_used(old_space_used());
   255     old_collection_counters()->update_all();
   256     young_collection_counters()->update_all();
   257   }
   258 }
   260 void G1MonitoringSupport::update_eden_size() {
   261   recalculate_eden_size();
   262   if (UsePerfData) {
   263     eden_counters()->update_used(eden_space_used());
   264   }
   265 }

mercurial