Mercurial > hg > truffle
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 } |