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 */
24
25 #include "precompiled.hpp"
26 #include "memory/blockOffsetTable.inline.hpp"
27 #include "memory/gcLocker.hpp"
28 #include "memory/generationSpec.hpp"
29 #include "memory/genOopClosures.inline.hpp"
30 #include "memory/genRemSet.hpp"
31 #include "memory/iterator.hpp"
32 #include "memory/memRegion.hpp"
33 #include "memory/space.inline.hpp"
34 #include "runtime/java.hpp"
35
36 CardGeneration::CardGeneration(ReservedSpace rs, size_t initial_byte_size,
37 int level,
38 GenRemSet* remset) :
39 Generation(rs, initial_byte_size, level), _rs(remset),
40 _shrink_factor(0), _min_heap_delta_bytes(), _capacity_at_prologue(),
41 _used_at_prologue()
42 {
43 HeapWord* start = (HeapWord*)rs.base();
44 size_t reserved_byte_size = rs.size();
45 assert((uintptr_t(start) & 3) == 0, "bad alignment");
46 assert((reserved_byte_size & 3) == 0, "bad alignment");
50 MemRegion committed_mr(start, heap_word_size(initial_byte_size));
51 _rs->resize_covered_region(committed_mr);
52 if (_bts == NULL)
53 vm_exit_during_initialization("Could not allocate a BlockOffsetArray");
54
55 // Verify that the start and end of this generation is the start of a card.
56 // If this wasn't true, a single card could span more than on generation,
57 // which would cause problems when we commit/uncommit memory, and when we
58 // clear and dirty cards.
59 guarantee(_rs->is_aligned(reserved_mr.start()), "generation must be card aligned");
60 if (reserved_mr.end() != Universe::heap()->reserved_region().end()) {
61 // Don't check at the very end of the heap as we'll assert that we're probing off
62 // the end if we try.
63 guarantee(_rs->is_aligned(reserved_mr.end()), "generation must be card aligned");
64 }
65 _min_heap_delta_bytes = MinHeapDeltaBytes;
66 _capacity_at_prologue = initial_byte_size;
67 _used_at_prologue = 0;
68 }
69
70 bool CardGeneration::expand(size_t bytes, size_t expand_bytes) {
71 assert_locked_or_safepoint(Heap_lock);
72 if (bytes == 0) {
73 return true; // That's what grow_by(0) would return
74 }
75 size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes);
76 if (aligned_bytes == 0){
77 // The alignment caused the number of bytes to wrap. An expand_by(0) will
78 // return true with the implication that an expansion was done when it
79 // was not. A call to expand implies a best effort to expand by "bytes"
80 // but not a guarantee. Align down to give a best effort. This is likely
81 // the most that the generation can expand since it has some capacity to
82 // start with.
83 aligned_bytes = ReservedSpace::page_align_size_down(bytes);
84 }
85 size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
86 bool success = false;
87 if (aligned_expand_bytes > aligned_bytes) {
88 success = grow_by(aligned_expand_bytes);
89 }
90 if (!success) {
91 success = grow_by(aligned_bytes);
92 }
93 if (!success) {
94 success = grow_to_reserved();
95 }
96 if (PrintGC && Verbose) {
97 if (success && GC_locker::is_active_and_needs_gc()) {
98 gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
99 }
100 }
101
102 return success;
103 }
104
105 // No young generation references, clear this generation's cards.
106 void CardGeneration::clear_remembered_set() {
107 _rs->clear(reserved());
108 }
109
110 // Objects in this generation may have moved, invalidate this
111 // generation's cards.
112 void CardGeneration::invalidate_remembered_set() {
113 _rs->invalidate(used_region());
114 }
115
116 void CardGeneration::compute_new_size() {
117 assert(_shrink_factor <= 100, "invalid shrink factor");
118 size_t current_shrink_factor = _shrink_factor;
119 _shrink_factor = 0;
120
121 // We don't have floating point command-line arguments
122 // Note: argument processing ensures that MinHeapFreeRatio < 100.
123 const double minimum_free_percentage = MinHeapFreeRatio / 100.0;
124 const double maximum_used_percentage = 1.0 - minimum_free_percentage;
125
126 // Compute some numbers about the state of the heap.
127 const size_t used_after_gc = used();
128 const size_t capacity_after_gc = capacity();
129
130 const double min_tmp = used_after_gc / maximum_used_percentage;
131 size_t minimum_desired_capacity = (size_t)MIN2(min_tmp, double(max_uintx));
132 // Don't shrink less than the initial generation size
133 minimum_desired_capacity = MAX2(minimum_desired_capacity,
134 spec()->init_size());
135 assert(used_after_gc <= minimum_desired_capacity, "sanity check");
252 gclog_or_tty->print_cr(" "
253 " aggressive shrinking:"
254 " _capacity_at_prologue: %.1fK"
255 " capacity_after_gc: %.1fK"
256 " expansion_for_promotion: %.1fK"
257 " shrink_bytes: %.1fK",
258 capacity_after_gc / (double) K,
259 _capacity_at_prologue / (double) K,
260 expansion_for_promotion / (double) K,
261 shrink_bytes / (double) K);
262 }
263 }
264 // Don't shrink unless it's significant
265 if (shrink_bytes >= _min_heap_delta_bytes) {
266 shrink(shrink_bytes);
267 }
268 }
269
270 // Currently nothing to do.
271 void CardGeneration::prepare_for_verify() {}
|
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 */
24
25 #include "precompiled.hpp"
26
27 #include "memory/blockOffsetTable.inline.hpp"
28 #include "memory/cardGeneration.inline.hpp"
29 #include "memory/gcLocker.hpp"
30 #include "memory/generationSpec.hpp"
31 #include "memory/genOopClosures.inline.hpp"
32 #include "memory/genRemSet.hpp"
33 #include "memory/iterator.hpp"
34 #include "memory/memRegion.hpp"
35 #include "memory/space.inline.hpp"
36 #include "runtime/java.hpp"
37
38 CardGeneration::CardGeneration(ReservedSpace rs, size_t initial_byte_size,
39 int level,
40 GenRemSet* remset) :
41 Generation(rs, initial_byte_size, level), _rs(remset),
42 _shrink_factor(0), _min_heap_delta_bytes(), _capacity_at_prologue(),
43 _used_at_prologue()
44 {
45 HeapWord* start = (HeapWord*)rs.base();
46 size_t reserved_byte_size = rs.size();
47 assert((uintptr_t(start) & 3) == 0, "bad alignment");
48 assert((reserved_byte_size & 3) == 0, "bad alignment");
52 MemRegion committed_mr(start, heap_word_size(initial_byte_size));
53 _rs->resize_covered_region(committed_mr);
54 if (_bts == NULL)
55 vm_exit_during_initialization("Could not allocate a BlockOffsetArray");
56
57 // Verify that the start and end of this generation is the start of a card.
58 // If this wasn't true, a single card could span more than on generation,
59 // which would cause problems when we commit/uncommit memory, and when we
60 // clear and dirty cards.
61 guarantee(_rs->is_aligned(reserved_mr.start()), "generation must be card aligned");
62 if (reserved_mr.end() != Universe::heap()->reserved_region().end()) {
63 // Don't check at the very end of the heap as we'll assert that we're probing off
64 // the end if we try.
65 guarantee(_rs->is_aligned(reserved_mr.end()), "generation must be card aligned");
66 }
67 _min_heap_delta_bytes = MinHeapDeltaBytes;
68 _capacity_at_prologue = initial_byte_size;
69 _used_at_prologue = 0;
70 }
71
72 bool CardGeneration::grow_by(size_t bytes) {
73 assert_correct_size_change_locking();
74 bool result = _virtual_space.expand_by(bytes);
75 if (result) {
76 size_t new_word_size =
77 heap_word_size(_virtual_space.committed_size());
78 MemRegion mr(space()->bottom(), new_word_size);
79 // Expand card table
80 Universe::heap()->barrier_set()->resize_covered_region(mr);
81 // Expand shared block offset array
82 _bts->resize(new_word_size);
83
84 // Fix for bug #4668531
85 if (ZapUnusedHeapArea) {
86 MemRegion mangle_region(space()->end(),
87 (HeapWord*)_virtual_space.high());
88 SpaceMangler::mangle_region(mangle_region);
89 }
90
91 // Expand space -- also expands space's BOT
92 // (which uses (part of) shared array above)
93 space()->set_end((HeapWord*)_virtual_space.high());
94
95 // update the space and generation capacity counters
96 update_counters();
97
98 if (Verbose && PrintGC) {
99 size_t new_mem_size = _virtual_space.committed_size();
100 size_t old_mem_size = new_mem_size - bytes;
101 gclog_or_tty->print_cr("Expanding %s from " SIZE_FORMAT "K by "
102 SIZE_FORMAT "K to " SIZE_FORMAT "K",
103 name(), old_mem_size/K, bytes/K, new_mem_size/K);
104 }
105 }
106 return result;
107 }
108
109 bool CardGeneration::expand(size_t bytes, size_t expand_bytes) {
110 assert_locked_or_safepoint(Heap_lock);
111 if (bytes == 0) {
112 return true; // That's what grow_by(0) would return
113 }
114 size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes);
115 if (aligned_bytes == 0){
116 // The alignment caused the number of bytes to wrap. An expand_by(0) will
117 // return true with the implication that an expansion was done when it
118 // was not. A call to expand implies a best effort to expand by "bytes"
119 // but not a guarantee. Align down to give a best effort. This is likely
120 // the most that the generation can expand since it has some capacity to
121 // start with.
122 aligned_bytes = ReservedSpace::page_align_size_down(bytes);
123 }
124 size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
125 bool success = false;
126 if (aligned_expand_bytes > aligned_bytes) {
127 success = grow_by(aligned_expand_bytes);
128 }
129 if (!success) {
130 success = grow_by(aligned_bytes);
131 }
132 if (!success) {
133 success = grow_to_reserved();
134 }
135 if (PrintGC && Verbose) {
136 if (success && GC_locker::is_active_and_needs_gc()) {
137 gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
138 }
139 }
140
141 return success;
142 }
143
144 bool CardGeneration::grow_to_reserved() {
145 assert_correct_size_change_locking();
146 bool success = true;
147 const size_t remaining_bytes = _virtual_space.uncommitted_size();
148 if (remaining_bytes > 0) {
149 success = grow_by(remaining_bytes);
150 DEBUG_ONLY(if (!success) warning("grow to reserved failed");)
151 }
152 return success;
153 }
154
155 void CardGeneration::shrink(size_t bytes) {
156 assert_correct_size_change_locking();
157
158 size_t size = ReservedSpace::page_align_size_down(bytes);
159 if (size == 0) {
160 return;
161 }
162
163 // Shrink committed space
164 _virtual_space.shrink_by(size);
165 // Shrink space; this also shrinks the space's BOT
166 space()->set_end((HeapWord*) _virtual_space.high());
167 size_t new_word_size = heap_word_size(space()->capacity());
168 // Shrink the shared block offset array
169 _bts->resize(new_word_size);
170 MemRegion mr(space()->bottom(), new_word_size);
171 // Shrink the card table
172 Universe::heap()->barrier_set()->resize_covered_region(mr);
173
174 if (Verbose && PrintGC) {
175 size_t new_mem_size = _virtual_space.committed_size();
176 size_t old_mem_size = new_mem_size + size;
177 gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K to " SIZE_FORMAT "K",
178 name(), old_mem_size/K, new_mem_size/K);
179 }
180 }
181
182 // No young generation references, clear this generation's cards.
183 void CardGeneration::clear_remembered_set() {
184 _rs->clear(reserved());
185 }
186
187
188 // Objects in this generation may have moved, invalidate this
189 // generation's cards.
190 void CardGeneration::invalidate_remembered_set() {
191 _rs->invalidate(used_region());
192 }
193
194
195 void CardGeneration::compute_new_size() {
196 assert(_shrink_factor <= 100, "invalid shrink factor");
197 size_t current_shrink_factor = _shrink_factor;
198 _shrink_factor = 0;
199
200 // We don't have floating point command-line arguments
201 // Note: argument processing ensures that MinHeapFreeRatio < 100.
202 const double minimum_free_percentage = MinHeapFreeRatio / 100.0;
203 const double maximum_used_percentage = 1.0 - minimum_free_percentage;
204
205 // Compute some numbers about the state of the heap.
206 const size_t used_after_gc = used();
207 const size_t capacity_after_gc = capacity();
208
209 const double min_tmp = used_after_gc / maximum_used_percentage;
210 size_t minimum_desired_capacity = (size_t)MIN2(min_tmp, double(max_uintx));
211 // Don't shrink less than the initial generation size
212 minimum_desired_capacity = MAX2(minimum_desired_capacity,
213 spec()->init_size());
214 assert(used_after_gc <= minimum_desired_capacity, "sanity check");
331 gclog_or_tty->print_cr(" "
332 " aggressive shrinking:"
333 " _capacity_at_prologue: %.1fK"
334 " capacity_after_gc: %.1fK"
335 " expansion_for_promotion: %.1fK"
336 " shrink_bytes: %.1fK",
337 capacity_after_gc / (double) K,
338 _capacity_at_prologue / (double) K,
339 expansion_for_promotion / (double) K,
340 shrink_bytes / (double) K);
341 }
342 }
343 // Don't shrink unless it's significant
344 if (shrink_bytes >= _min_heap_delta_bytes) {
345 shrink(shrink_bytes);
346 }
347 }
348
349 // Currently nothing to do.
350 void CardGeneration::prepare_for_verify() {}
351
352 void CardGeneration::space_iterate(SpaceClosure* blk,
353 bool usedOnly) {
354 blk->do_space(space());
355 }
356
357 void CardGeneration::younger_refs_iterate(OopsInGenClosure* blk) {
358 blk->set_generation(this);
359 younger_refs_in_space_iterate(space(), blk);
360 blk->reset_generation();
361 }
|