comparison src/share/vm/memory/tenuredGeneration.cpp @ 9072:8617e38bb4cb

8008508: CMS does not correctly reduce heap size after a Full GC Reviewed-by: johnc, ysr
author jmasa
date Mon, 11 Feb 2013 10:31:56 -0800
parents db9981fd3124
children de6a9e811145
comparison
equal deleted inserted replaced
9071:68fe50d4f1d5 9072:8617e38bb4cb
37 37
38 TenuredGeneration::TenuredGeneration(ReservedSpace rs, 38 TenuredGeneration::TenuredGeneration(ReservedSpace rs,
39 size_t initial_byte_size, int level, 39 size_t initial_byte_size, int level,
40 GenRemSet* remset) : 40 GenRemSet* remset) :
41 OneContigSpaceCardGeneration(rs, initial_byte_size, 41 OneContigSpaceCardGeneration(rs, initial_byte_size,
42 MinHeapDeltaBytes, level, remset, NULL) 42 level, remset, NULL)
43 { 43 {
44 HeapWord* bottom = (HeapWord*) _virtual_space.low(); 44 HeapWord* bottom = (HeapWord*) _virtual_space.low();
45 HeapWord* end = (HeapWord*) _virtual_space.high(); 45 HeapWord* end = (HeapWord*) _virtual_space.high();
46 _the_space = new TenuredSpace(_bts, MemRegion(bottom, end)); 46 _the_space = new TenuredSpace(_bts, MemRegion(bottom, end));
47 _the_space->reset_saved_mark(); 47 _the_space->reset_saved_mark();
84 84
85 const char* TenuredGeneration::name() const { 85 const char* TenuredGeneration::name() const {
86 return "tenured generation"; 86 return "tenured generation";
87 } 87 }
88 88
89 void TenuredGeneration::compute_new_size() {
90 assert(_shrink_factor <= 100, "invalid shrink factor");
91 size_t current_shrink_factor = _shrink_factor;
92 _shrink_factor = 0;
93
94 // We don't have floating point command-line arguments
95 // Note: argument processing ensures that MinHeapFreeRatio < 100.
96 const double minimum_free_percentage = MinHeapFreeRatio / 100.0;
97 const double maximum_used_percentage = 1.0 - minimum_free_percentage;
98
99 // Compute some numbers about the state of the heap.
100 const size_t used_after_gc = used();
101 const size_t capacity_after_gc = capacity();
102
103 const double min_tmp = used_after_gc / maximum_used_percentage;
104 size_t minimum_desired_capacity = (size_t)MIN2(min_tmp, double(max_uintx));
105 // Don't shrink less than the initial generation size
106 minimum_desired_capacity = MAX2(minimum_desired_capacity,
107 spec()->init_size());
108 assert(used_after_gc <= minimum_desired_capacity, "sanity check");
109
110 if (PrintGC && Verbose) {
111 const size_t free_after_gc = free();
112 const double free_percentage = ((double)free_after_gc) / capacity_after_gc;
113 gclog_or_tty->print_cr("TenuredGeneration::compute_new_size: ");
114 gclog_or_tty->print_cr(" "
115 " minimum_free_percentage: %6.2f"
116 " maximum_used_percentage: %6.2f",
117 minimum_free_percentage,
118 maximum_used_percentage);
119 gclog_or_tty->print_cr(" "
120 " free_after_gc : %6.1fK"
121 " used_after_gc : %6.1fK"
122 " capacity_after_gc : %6.1fK",
123 free_after_gc / (double) K,
124 used_after_gc / (double) K,
125 capacity_after_gc / (double) K);
126 gclog_or_tty->print_cr(" "
127 " free_percentage: %6.2f",
128 free_percentage);
129 }
130
131 if (capacity_after_gc < minimum_desired_capacity) {
132 // If we have less free space than we want then expand
133 size_t expand_bytes = minimum_desired_capacity - capacity_after_gc;
134 // Don't expand unless it's significant
135 if (expand_bytes >= _min_heap_delta_bytes) {
136 expand(expand_bytes, 0); // safe if expansion fails
137 }
138 if (PrintGC && Verbose) {
139 gclog_or_tty->print_cr(" expanding:"
140 " minimum_desired_capacity: %6.1fK"
141 " expand_bytes: %6.1fK"
142 " _min_heap_delta_bytes: %6.1fK",
143 minimum_desired_capacity / (double) K,
144 expand_bytes / (double) K,
145 _min_heap_delta_bytes / (double) K);
146 }
147 return;
148 }
149
150 // No expansion, now see if we want to shrink
151 size_t shrink_bytes = 0;
152 // We would never want to shrink more than this
153 size_t max_shrink_bytes = capacity_after_gc - minimum_desired_capacity;
154
155 if (MaxHeapFreeRatio < 100) {
156 const double maximum_free_percentage = MaxHeapFreeRatio / 100.0;
157 const double minimum_used_percentage = 1.0 - maximum_free_percentage;
158 const double max_tmp = used_after_gc / minimum_used_percentage;
159 size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(max_uintx));
160 maximum_desired_capacity = MAX2(maximum_desired_capacity,
161 spec()->init_size());
162 if (PrintGC && Verbose) {
163 gclog_or_tty->print_cr(" "
164 " maximum_free_percentage: %6.2f"
165 " minimum_used_percentage: %6.2f",
166 maximum_free_percentage,
167 minimum_used_percentage);
168 gclog_or_tty->print_cr(" "
169 " _capacity_at_prologue: %6.1fK"
170 " minimum_desired_capacity: %6.1fK"
171 " maximum_desired_capacity: %6.1fK",
172 _capacity_at_prologue / (double) K,
173 minimum_desired_capacity / (double) K,
174 maximum_desired_capacity / (double) K);
175 }
176 assert(minimum_desired_capacity <= maximum_desired_capacity,
177 "sanity check");
178
179 if (capacity_after_gc > maximum_desired_capacity) {
180 // Capacity too large, compute shrinking size
181 shrink_bytes = capacity_after_gc - maximum_desired_capacity;
182 // We don't want shrink all the way back to initSize if people call
183 // System.gc(), because some programs do that between "phases" and then
184 // we'd just have to grow the heap up again for the next phase. So we
185 // damp the shrinking: 0% on the first call, 10% on the second call, 40%
186 // on the third call, and 100% by the fourth call. But if we recompute
187 // size without shrinking, it goes back to 0%.
188 shrink_bytes = shrink_bytes / 100 * current_shrink_factor;
189 assert(shrink_bytes <= max_shrink_bytes, "invalid shrink size");
190 if (current_shrink_factor == 0) {
191 _shrink_factor = 10;
192 } else {
193 _shrink_factor = MIN2(current_shrink_factor * 4, (size_t) 100);
194 }
195 if (PrintGC && Verbose) {
196 gclog_or_tty->print_cr(" "
197 " shrinking:"
198 " initSize: %.1fK"
199 " maximum_desired_capacity: %.1fK",
200 spec()->init_size() / (double) K,
201 maximum_desired_capacity / (double) K);
202 gclog_or_tty->print_cr(" "
203 " shrink_bytes: %.1fK"
204 " current_shrink_factor: %d"
205 " new shrink factor: %d"
206 " _min_heap_delta_bytes: %.1fK",
207 shrink_bytes / (double) K,
208 current_shrink_factor,
209 _shrink_factor,
210 _min_heap_delta_bytes / (double) K);
211 }
212 }
213 }
214
215 if (capacity_after_gc > _capacity_at_prologue) {
216 // We might have expanded for promotions, in which case we might want to
217 // take back that expansion if there's room after GC. That keeps us from
218 // stretching the heap with promotions when there's plenty of room.
219 size_t expansion_for_promotion = capacity_after_gc - _capacity_at_prologue;
220 expansion_for_promotion = MIN2(expansion_for_promotion, max_shrink_bytes);
221 // We have two shrinking computations, take the largest
222 shrink_bytes = MAX2(shrink_bytes, expansion_for_promotion);
223 assert(shrink_bytes <= max_shrink_bytes, "invalid shrink size");
224 if (PrintGC && Verbose) {
225 gclog_or_tty->print_cr(" "
226 " aggressive shrinking:"
227 " _capacity_at_prologue: %.1fK"
228 " capacity_after_gc: %.1fK"
229 " expansion_for_promotion: %.1fK"
230 " shrink_bytes: %.1fK",
231 capacity_after_gc / (double) K,
232 _capacity_at_prologue / (double) K,
233 expansion_for_promotion / (double) K,
234 shrink_bytes / (double) K);
235 }
236 }
237 // Don't shrink unless it's significant
238 if (shrink_bytes >= _min_heap_delta_bytes) {
239 shrink(shrink_bytes);
240 }
241 assert(used() == used_after_gc && used_after_gc <= capacity(),
242 "sanity check");
243 }
244
245 void TenuredGeneration::gc_prologue(bool full) { 89 void TenuredGeneration::gc_prologue(bool full) {
246 _capacity_at_prologue = capacity(); 90 _capacity_at_prologue = capacity();
247 _used_at_prologue = used(); 91 _used_at_prologue = used();
248 if (VerifyBeforeGC) { 92 if (VerifyBeforeGC) {
249 verify_alloc_buffers_clean(); 93 verify_alloc_buffers_clean();
310 retire_alloc_buffers_before_full_gc(); 154 retire_alloc_buffers_before_full_gc();
311 OneContigSpaceCardGeneration::collect(full, clear_all_soft_refs, 155 OneContigSpaceCardGeneration::collect(full, clear_all_soft_refs,
312 size, is_tlab); 156 size, is_tlab);
313 } 157 }
314 158
159 void TenuredGeneration::compute_new_size() {
160 assert_locked_or_safepoint(Heap_lock);
161
162 // Compute some numbers about the state of the heap.
163 const size_t used_after_gc = used();
164 const size_t capacity_after_gc = capacity();
165
166 CardGeneration::compute_new_size();
167
168 assert(used() == used_after_gc && used_after_gc <= capacity(),
169 err_msg("used: " SIZE_FORMAT " used_after_gc: " SIZE_FORMAT
170 " capacity: " SIZE_FORMAT, used(), used_after_gc, capacity()));
171 }
315 void TenuredGeneration::update_gc_stats(int current_level, 172 void TenuredGeneration::update_gc_stats(int current_level,
316 bool full) { 173 bool full) {
317 // If the next lower level(s) has been collected, gather any statistics 174 // If the next lower level(s) has been collected, gather any statistics
318 // that are of interest at this point. 175 // that are of interest at this point.
319 if (!full && (current_level + 1) == level()) { 176 if (!full && (current_level + 1) == level()) {