comparison src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp @ 3980:8229bd737950

7075646: G1: fix inconsistencies in the monitoring data Summary: Fixed a few inconsistencies in the monitoring data, in particular when reported from jstat. Reviewed-by: jmasa, brutisso, johnc
author tonyp
date Fri, 23 Sep 2011 16:07:49 -0400
parents b52782ae3880
children b5290bf0a9e4
comparison
equal deleted inserted replaced
3979:4dfb2df418f2 3980:8229bd737950
25 #include "precompiled.hpp" 25 #include "precompiled.hpp"
26 #include "gc_implementation/g1/g1MonitoringSupport.hpp" 26 #include "gc_implementation/g1/g1MonitoringSupport.hpp"
27 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" 27 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
28 #include "gc_implementation/g1/g1CollectorPolicy.hpp" 28 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
29 29
30 G1MonitoringSupport::G1MonitoringSupport(G1CollectedHeap* g1h, 30 G1GenerationCounters::G1GenerationCounters(G1MonitoringSupport* g1mm,
31 VirtualSpace* g1_storage_addr) : 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) { }
38
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 }
49
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 }
58
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 }
64
65 void G1OldGenerationCounters::update_all() {
66 size_t committed =
67 G1MonitoringSupport::pad_capacity(_g1mm->old_gen_committed());
68 _current_size->set_value(committed);
69 }
70
71 G1MonitoringSupport::G1MonitoringSupport(G1CollectedHeap* g1h) :
32 _g1h(g1h), 72 _g1h(g1h),
33 _incremental_collection_counters(NULL), 73 _incremental_collection_counters(NULL),
34 _full_collection_counters(NULL), 74 _full_collection_counters(NULL),
35 _non_young_collection_counters(NULL), 75 _old_collection_counters(NULL),
36 _old_space_counters(NULL), 76 _old_space_counters(NULL),
37 _young_collection_counters(NULL), 77 _young_collection_counters(NULL),
38 _eden_counters(NULL), 78 _eden_counters(NULL),
39 _from_counters(NULL), 79 _from_counters(NULL),
40 _to_counters(NULL), 80 _to_counters(NULL),
41 _g1_storage_addr(g1_storage_addr) 81
42 { 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) {
89
90 _overall_reserved = g1h->max_capacity();
91 recalculate_sizes();
92
43 // Counters for GC collections 93 // Counters for GC collections
44 // 94 //
45 // name "collector.0". In a generational collector this would be the 95 // name "collector.0". In a generational collector this would be the
46 // young generation collection. 96 // young generation collection.
47 _incremental_collection_counters = 97 _incremental_collection_counters =
67 // 117 //
68 // name "generation.1" This is logically the old generation in 118 // name "generation.1" This is logically the old generation in
69 // generational GC terms. The "1, 1" parameters are for 119 // generational GC terms. The "1, 1" parameters are for
70 // the n-th generation (=1) with 1 space. 120 // the n-th generation (=1) with 1 space.
71 // Counters are created from minCapacity, maxCapacity, and capacity 121 // Counters are created from minCapacity, maxCapacity, and capacity
72 _non_young_collection_counters = 122 _old_collection_counters = new G1OldGenerationCounters(this, "old");
73 new GenerationCounters("whole heap", 1, 1, _g1_storage_addr);
74 123
75 // name "generation.1.space.0" 124 // name "generation.1.space.0"
76 // Counters are created from maxCapacity, capacity, initCapacity, 125 // Counters are created from maxCapacity, capacity, initCapacity,
77 // and used. 126 // and used.
78 _old_space_counters = new HSpaceCounters("space", 0, 127 _old_space_counters = new HSpaceCounters("space", 0 /* ordinal */,
79 _g1h->max_capacity(), _g1h->capacity(), _non_young_collection_counters); 128 pad_capacity(overall_reserved()) /* max_capacity */,
129 pad_capacity(old_space_committed()) /* init_capacity */,
130 _old_collection_counters);
80 131
81 // Young collection set 132 // Young collection set
82 // name "generation.0". This is logically the young generation. 133 // name "generation.0". This is logically the young generation.
83 // The "0, 3" are paremeters for the n-th genertaion (=0) with 3 spaces. 134 // The "0, 3" are paremeters for the n-th genertaion (=0) with 3 spaces.
84 // See _non_young_collection_counters for additional counters 135 // See _old_collection_counters for additional counters
85 _young_collection_counters = new GenerationCounters("young", 0, 3, NULL); 136 _young_collection_counters = new G1YoungGenerationCounters(this, "young");
86 137
87 // Replace "max_heap_byte_size() with maximum young gen size for
88 // g1Collectedheap
89 // name "generation.0.space.0" 138 // name "generation.0.space.0"
90 // See _old_space_counters for additional counters 139 // See _old_space_counters for additional counters
91 _eden_counters = new HSpaceCounters("eden", 0, 140 _eden_counters = new HSpaceCounters("eden", 0 /* ordinal */,
92 _g1h->max_capacity(), eden_space_committed(), 141 pad_capacity(overall_reserved()) /* max_capacity */,
142 pad_capacity(eden_space_committed()) /* init_capacity */,
93 _young_collection_counters); 143 _young_collection_counters);
94 144
95 // name "generation.0.space.1" 145 // name "generation.0.space.1"
96 // See _old_space_counters for additional counters 146 // See _old_space_counters for additional counters
97 // Set the arguments to indicate that this survivor space is not used. 147 // Set the arguments to indicate that this survivor space is not used.
98 _from_counters = new HSpaceCounters("s0", 1, (long) 0, (long) 0, 148 _from_counters = new HSpaceCounters("s0", 1 /* ordinal */,
149 pad_capacity(0) /* max_capacity */,
150 pad_capacity(0) /* init_capacity */,
99 _young_collection_counters); 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);
100 156
101 // name "generation.0.space.2" 157 // name "generation.0.space.2"
102 // See _old_space_counters for additional counters 158 // See _old_space_counters for additional counters
103 _to_counters = new HSpaceCounters("s1", 2, 159 _to_counters = new HSpaceCounters("s1", 2 /* ordinal */,
104 _g1h->max_capacity(), 160 pad_capacity(overall_reserved()) /* max_capacity */,
105 survivor_space_committed(), 161 pad_capacity(survivor_space_committed()) /* init_capacity */,
106 _young_collection_counters); 162 _young_collection_counters);
107 } 163 }
108 164
109 size_t G1MonitoringSupport::overall_committed() { 165 void G1MonitoringSupport::recalculate_sizes() {
110 return g1h()->capacity(); 166 G1CollectedHeap* g1 = g1h();
111 } 167
112 168 // Recalculate all the sizes from scratch. We assume that this is
113 size_t G1MonitoringSupport::overall_used() { 169 // called at a point where no concurrent updates to the various
114 return g1h()->used_unlocked(); 170 // values we read here are possible (i.e., at a STW phase at the end
115 } 171 // of a GC).
116 172
117 size_t G1MonitoringSupport::eden_space_committed() { 173 size_t young_list_length = g1->young_list()->length();
118 return MAX2(eden_space_used(), (size_t) HeapRegion::GrainBytes); 174 size_t survivor_list_length = g1->g1_policy()->recorded_survivor_regions();
119 } 175 assert(young_list_length >= survivor_list_length, "invariant");
120 176 size_t eden_list_length = young_list_length - survivor_list_length;
121 size_t G1MonitoringSupport::eden_space_used() { 177 // Max length includes any potential extensions to the young gen
122 size_t young_list_length = g1h()->young_list()->length(); 178 // we'll do when the GC locker is active.
123 size_t eden_used = young_list_length * HeapRegion::GrainBytes; 179 size_t young_list_max_length = g1->g1_policy()->young_list_max_length();
124 size_t survivor_used = survivor_space_used(); 180 assert(young_list_max_length >= survivor_list_length, "invariant");
125 eden_used = subtract_up_to_zero(eden_used, survivor_used); 181 size_t eden_list_max_length = young_list_max_length - survivor_list_length;
126 return eden_used; 182
127 } 183 _overall_used = g1->used_unlocked();
128 184 _eden_used = eden_list_length * HeapRegion::GrainBytes;
129 size_t G1MonitoringSupport::survivor_space_committed() { 185 _survivor_used = survivor_list_length * HeapRegion::GrainBytes;
130 return MAX2(survivor_space_used(), 186 _young_region_num = young_list_length;
131 (size_t) HeapRegion::GrainBytes); 187 _old_used = subtract_up_to_zero(_overall_used, _eden_used + _survivor_used);
132 } 188
133 189 // First calculate the committed sizes that can be calculated independently.
134 size_t G1MonitoringSupport::survivor_space_used() { 190 _survivor_committed = _survivor_used;
135 size_t survivor_num = g1h()->g1_policy()->recorded_survivor_regions(); 191 _old_committed = HeapRegion::align_up_to_region_byte_size(_old_used);
136 size_t survivor_used = survivor_num * HeapRegion::GrainBytes; 192
137 return survivor_used; 193 // Next, start with the overall committed size.
138 } 194 _overall_committed = g1->capacity();
139 195 size_t committed = _overall_committed;
140 size_t G1MonitoringSupport::old_space_committed() { 196
141 size_t committed = overall_committed(); 197 // Remove the committed size we have calculated so far (for the
142 size_t eden_committed = eden_space_committed(); 198 // survivor and old space).
143 size_t survivor_committed = survivor_space_committed(); 199 assert(committed >= (_survivor_committed + _old_committed), "sanity");
144 committed = subtract_up_to_zero(committed, eden_committed); 200 committed -= _survivor_committed + _old_committed;
145 committed = subtract_up_to_zero(committed, survivor_committed); 201
146 committed = MAX2(committed, (size_t) HeapRegion::GrainBytes); 202 // Next, calculate and remove the committed size for the eden.
147 return committed; 203 _eden_committed = eden_list_max_length * HeapRegion::GrainBytes;
148 } 204 // Somewhat defensive: be robust in case there are inaccuracies in
149 205 // the calculations
150 // See the comment near the top of g1MonitoringSupport.hpp for 206 _eden_committed = MIN2(_eden_committed, committed);
151 // an explanation of these calculations for "used" and "capacity". 207 committed -= _eden_committed;
152 size_t G1MonitoringSupport::old_space_used() { 208
153 size_t used = overall_used(); 209 // Finally, give the rest to the old space...
154 size_t eden_used = eden_space_used(); 210 _old_committed += committed;
155 size_t survivor_used = survivor_space_used(); 211 // ..and calculate the young gen committed.
156 used = subtract_up_to_zero(used, eden_used); 212 _young_gen_committed = _eden_committed + _survivor_committed;
157 used = subtract_up_to_zero(used, survivor_used); 213
158 return used; 214 assert(_overall_committed ==
159 } 215 (_eden_committed + _survivor_committed + _old_committed),
160 216 "the committed sizes should add up");
161 void G1MonitoringSupport::update_counters() { 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 }
226
227 void G1MonitoringSupport::recalculate_eden_size() {
228 G1CollectedHeap* g1 = g1h();
229
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).
232
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 }
243
244 void G1MonitoringSupport::update_sizes() {
245 recalculate_sizes();
162 if (UsePerfData) { 246 if (UsePerfData) {
163 eden_counters()->update_capacity(eden_space_committed()); 247 eden_counters()->update_capacity(pad_capacity(eden_space_committed()));
164 eden_counters()->update_used(eden_space_used()); 248 eden_counters()->update_used(eden_space_used());
165 to_counters()->update_capacity(survivor_space_committed()); 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()));
166 to_counters()->update_used(survivor_space_used()); 252 to_counters()->update_used(survivor_space_used());
167 old_space_counters()->update_capacity(old_space_committed()); 253 old_space_counters()->update_capacity(pad_capacity(old_space_committed()));
168 old_space_counters()->update_used(old_space_used()); 254 old_space_counters()->update_used(old_space_used());
169 non_young_collection_counters()->update_all(); 255 old_collection_counters()->update_all();
256 young_collection_counters()->update_all();
170 } 257 }
171 } 258 }
172 259
173 void G1MonitoringSupport::update_eden_counters() { 260 void G1MonitoringSupport::update_eden_size() {
261 recalculate_eden_size();
174 if (UsePerfData) { 262 if (UsePerfData) {
175 eden_counters()->update_capacity(eden_space_committed());
176 eden_counters()->update_used(eden_space_used()); 263 eden_counters()->update_used(eden_space_used());
177 } 264 }
178 } 265 }