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

Fri, 16 Dec 2011 02:14:27 -0500

author
tonyp
date
Fri, 16 Dec 2011 02:14:27 -0500
changeset 3337
41406797186b
parent 3180
81aa07130d30
child 3459
a8a126788ea0
permissions
-rw-r--r--

7113012: G1: rename not-fully-young GCs as "mixed"
Summary: Renamed partially-young GCs as mixed and fully-young GCs as young. Change all external output that includes those terms (GC log and GC ergo log) as well as any comments, fields, methods, etc. The changeset also includes very minor code tidying up (added some curly brackets).
Reviewed-by: johnc, brutisso

     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 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1MONITORINGSUPPORT_HPP
    26 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1MONITORINGSUPPORT_HPP
    28 #include "gc_implementation/shared/hSpaceCounters.hpp"
    30 class G1CollectedHeap;
    32 // Class for monitoring logical spaces in G1. It provides data for
    33 // both G1's jstat counters as well as G1's memory pools.
    34 //
    35 // G1 splits the heap into heap regions and each heap region belongs
    36 // to one of the following categories:
    37 //
    38 // * eden      : regions that have been allocated since the last GC
    39 // * survivors : regions with objects that survived the last few GCs
    40 // * old       : long-lived non-humongous regions
    41 // * humongous : humongous regions
    42 // * free      : free regions
    43 //
    44 // The combination of eden and survivor regions form the equivalent of
    45 // the young generation in the other GCs. The combination of old and
    46 // humongous regions form the equivalent of the old generation in the
    47 // other GCs. Free regions do not have a good equivalent in the other
    48 // GCs given that they can be allocated as any of the other region types.
    49 //
    50 // The monitoring tools expect the heap to contain a number of
    51 // generations (young, old, perm) and each generation to contain a
    52 // number of spaces (young: eden, survivors, old). Given that G1 does
    53 // not maintain those spaces physically (e.g., the set of
    54 // non-contiguous eden regions can be considered as a "logical"
    55 // space), we'll provide the illusion that those generations and
    56 // spaces exist. In reality, each generation and space refers to a set
    57 // of heap regions that are potentially non-contiguous.
    58 //
    59 // This class provides interfaces to access the min, current, and max
    60 // capacity and current occupancy for each of G1's logical spaces and
    61 // generations we expose to the monitoring tools. Also provided are
    62 // counters for G1 concurrent collections and stop-the-world full heap
    63 // collections.
    64 //
    65 // Below is a description of how the various sizes are calculated.
    66 //
    67 // * Current Capacity
    68 //
    69 //    - heap_capacity = current heap capacity (e.g., current committed size)
    70 //    - young_gen_capacity = current max young gen target capacity
    71 //          (i.e., young gen target capacity + max allowed expansion capacity)
    72 //    - survivor_capacity = current survivor region capacity
    73 //    - eden_capacity = young_gen_capacity - survivor_capacity
    74 //    - old_capacity = heap_capacity - young_gen_capacity
    75 //
    76 //    What we do in the above is to distribute the free regions among
    77 //    eden_capacity and old_capacity.
    78 //
    79 // * Occupancy
    80 //
    81 //    - young_gen_used = current young region capacity
    82 //    - survivor_used = survivor_capacity
    83 //    - eden_used = young_gen_used - survivor_used
    84 //    - old_used = overall_used - young_gen_used
    85 //
    86 //    Unfortunately, we currently only keep track of the number of
    87 //    currently allocated young and survivor regions + the overall used
    88 //    bytes in the heap, so the above can be a little inaccurate.
    89 //
    90 // * Min Capacity
    91 //
    92 //    We set this to 0 for all spaces. We could consider setting the old
    93 //    min capacity to the min capacity of the heap (see 7078465).
    94 //
    95 // * Max Capacity
    96 //
    97 //    For jstat, we set the max capacity of all spaces to heap_capacity,
    98 //    given that we don't always have a reasonably upper bound on how big
    99 //    each space can grow. For the memory pools, we actually make the max
   100 //    capacity undefined. We could consider setting the old max capacity
   101 //    to the max capacity of the heap (see 7078465).
   102 //
   103 // If we had more accurate occupancy / capacity information per
   104 // region set the above calculations would be greatly simplified and
   105 // be made more accurate.
   106 //
   107 // We update all the above synchronously and we store the results in
   108 // fields so that we just read said fields when needed. A subtle point
   109 // is that all the above sizes need to be recalculated when the old
   110 // gen changes capacity (after a GC or after a humongous allocation)
   111 // but only the eden occupancy changes when a new eden region is
   112 // allocated. So, in the latter case we have minimal recalcuation to
   113 // do which is important as we want to keep the eden region allocation
   114 // path as low-overhead as possible.
   116 class G1MonitoringSupport : public CHeapObj {
   117   friend class VMStructs;
   119   G1CollectedHeap* _g1h;
   121   // jstat performance counters
   122   //  incremental collections both young and mixed
   123   CollectorCounters*   _incremental_collection_counters;
   124   //  full stop-the-world collections
   125   CollectorCounters*   _full_collection_counters;
   126   //  young collection set counters.  The _eden_counters,
   127   // _from_counters, and _to_counters are associated with
   128   // this "generational" counter.
   129   GenerationCounters*  _young_collection_counters;
   130   //  old collection set counters. The _old_space_counters
   131   // below are associated with this "generational" counter.
   132   GenerationCounters*  _old_collection_counters;
   133   // Counters for the capacity and used for
   134   //   the whole heap
   135   HSpaceCounters*      _old_space_counters;
   136   //   the young collection
   137   HSpaceCounters*      _eden_counters;
   138   //   the survivor collection (only one, _to_counters, is actively used)
   139   HSpaceCounters*      _from_counters;
   140   HSpaceCounters*      _to_counters;
   142   // When it's appropriate to recalculate the various sizes (at the
   143   // end of a GC, when a new eden region is allocated, etc.) we store
   144   // them here so that we can easily report them when needed and not
   145   // have to recalculate them every time.
   147   size_t _overall_reserved;
   148   size_t _overall_committed;
   149   size_t _overall_used;
   151   size_t _young_region_num;
   152   size_t _young_gen_committed;
   153   size_t _eden_committed;
   154   size_t _eden_used;
   155   size_t _survivor_committed;
   156   size_t _survivor_used;
   158   size_t _old_committed;
   159   size_t _old_used;
   161   G1CollectedHeap* g1h() { return _g1h; }
   163   // It returns x - y if x > y, 0 otherwise.
   164   // As described in the comment above, some of the inputs to the
   165   // calculations we have to do are obtained concurrently and hence
   166   // may be inconsistent with each other. So, this provides a
   167   // defensive way of performing the subtraction and avoids the value
   168   // going negative (which would mean a very large result, given that
   169   // the parameter are size_t).
   170   static size_t subtract_up_to_zero(size_t x, size_t y) {
   171     if (x > y) {
   172       return x - y;
   173     } else {
   174       return 0;
   175     }
   176   }
   178   // Recalculate all the sizes.
   179   void recalculate_sizes();
   180   // Recalculate only what's necessary when a new eden region is allocated.
   181   void recalculate_eden_size();
   183  public:
   184   G1MonitoringSupport(G1CollectedHeap* g1h);
   186   // Unfortunately, the jstat tool assumes that no space has 0
   187   // capacity. In our case, given that each space is logical, it's
   188   // possible that no regions will be allocated to it, hence to have 0
   189   // capacity (e.g., if there are no survivor regions, the survivor
   190   // space has 0 capacity). The way we deal with this is to always pad
   191   // each capacity value we report to jstat by a very small amount to
   192   // make sure that it's never zero. Given that we sometimes have to
   193   // report a capacity of a generation that contains several spaces
   194   // (e.g., young gen includes one eden, two survivor spaces), the
   195   // mult parameter is provided in order to adding the appropriate
   196   // padding multiple times so that the capacities add up correctly.
   197   static size_t pad_capacity(size_t size_bytes, size_t mult = 1) {
   198     return size_bytes + MinObjAlignmentInBytes * mult;
   199   }
   201   // Recalculate all the sizes from scratch and update all the jstat
   202   // counters accordingly.
   203   void update_sizes();
   204   // Recalculate only what's necessary when a new eden region is
   205   // allocated and update any jstat counters that need to be updated.
   206   void update_eden_size();
   208   CollectorCounters* incremental_collection_counters() {
   209     return _incremental_collection_counters;
   210   }
   211   CollectorCounters* full_collection_counters() {
   212     return _full_collection_counters;
   213   }
   214   GenerationCounters* young_collection_counters() {
   215     return _young_collection_counters;
   216   }
   217   GenerationCounters* old_collection_counters() {
   218     return _old_collection_counters;
   219   }
   220   HSpaceCounters*      old_space_counters() { return _old_space_counters; }
   221   HSpaceCounters*      eden_counters() { return _eden_counters; }
   222   HSpaceCounters*      from_counters() { return _from_counters; }
   223   HSpaceCounters*      to_counters() { return _to_counters; }
   225   // Monitoring support used by
   226   //   MemoryService
   227   //   jstat counters
   229   size_t overall_reserved()           { return _overall_reserved;     }
   230   size_t overall_committed()          { return _overall_committed;    }
   231   size_t overall_used()               { return _overall_used;         }
   233   size_t young_gen_committed()        { return _young_gen_committed;  }
   234   size_t young_gen_max()              { return overall_reserved();    }
   235   size_t eden_space_committed()       { return _eden_committed;       }
   236   size_t eden_space_used()            { return _eden_used;            }
   237   size_t survivor_space_committed()   { return _survivor_committed;   }
   238   size_t survivor_space_used()        { return _survivor_used;        }
   240   size_t old_gen_committed()          { return old_space_committed(); }
   241   size_t old_gen_max()                { return overall_reserved();    }
   242   size_t old_space_committed()        { return _old_committed;        }
   243   size_t old_space_used()             { return _old_used;             }
   244 };
   246 class G1GenerationCounters: public GenerationCounters {
   247 protected:
   248   G1MonitoringSupport* _g1mm;
   250 public:
   251   G1GenerationCounters(G1MonitoringSupport* g1mm,
   252                        const char* name, int ordinal, int spaces,
   253                        size_t min_capacity, size_t max_capacity,
   254                        size_t curr_capacity);
   255 };
   257 class G1YoungGenerationCounters: public G1GenerationCounters {
   258 public:
   259   G1YoungGenerationCounters(G1MonitoringSupport* g1mm, const char* name);
   260   virtual void update_all();
   261 };
   263 class G1OldGenerationCounters: public G1GenerationCounters {
   264 public:
   265   G1OldGenerationCounters(G1MonitoringSupport* g1mm, const char* name);
   266   virtual void update_all();
   267 };
   269 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1MONITORINGSUPPORT_HPP

mercurial