Fri, 16 Dec 2011 02:14:27 -0500
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