Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp @ 3772:6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
Summary: Perform a heap verification after the first phase of G1's full GC using objects' mark words to determine liveness. The third parameter of the heap verification routines, which was used in G1 to determine which marking bitmap to use in liveness calculations, has been changed from a boolean to an enum with values defined for using the mark word, and the 'prev' and 'next' bitmaps.
Reviewed-by: tonyp, ysr
author | johnc |
---|---|
date | Tue, 14 Jun 2011 11:01:10 -0700 |
parents | 2aa9ddbb9e60 |
children | c9ca3f51cf41 |
rev | line source |
---|---|
0 | 1 /* |
2251
336d17dff7cc
7014874: Incorrect COOPs modes on solaris-{sparcv9,amd64} with ParallelGC
kvn
parents:
1972
diff
changeset
|
2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1387
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1387
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1387
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "gc_implementation/parallelScavenge/adjoiningGenerations.hpp" | |
27 #include "gc_implementation/parallelScavenge/adjoiningVirtualSpaces.hpp" | |
28 #include "gc_implementation/parallelScavenge/cardTableExtension.hpp" | |
29 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" | |
30 #include "gc_implementation/parallelScavenge/generationSizer.hpp" | |
31 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp" | |
32 #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp" | |
33 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp" | |
34 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp" | |
35 #include "gc_implementation/parallelScavenge/psPromotionManager.hpp" | |
36 #include "gc_implementation/parallelScavenge/psScavenge.hpp" | |
37 #include "gc_implementation/parallelScavenge/vmPSOperations.hpp" | |
38 #include "memory/gcLocker.inline.hpp" | |
39 #include "oops/oop.inline.hpp" | |
40 #include "runtime/handles.inline.hpp" | |
41 #include "runtime/java.hpp" | |
42 #include "runtime/vmThread.hpp" | |
43 #include "utilities/vmError.hpp" | |
0 | 44 |
45 PSYoungGen* ParallelScavengeHeap::_young_gen = NULL; | |
46 PSOldGen* ParallelScavengeHeap::_old_gen = NULL; | |
47 PSPermGen* ParallelScavengeHeap::_perm_gen = NULL; | |
48 PSAdaptiveSizePolicy* ParallelScavengeHeap::_size_policy = NULL; | |
49 PSGCAdaptivePolicyCounters* ParallelScavengeHeap::_gc_policy_counters = NULL; | |
50 ParallelScavengeHeap* ParallelScavengeHeap::_psh = NULL; | |
51 GCTaskManager* ParallelScavengeHeap::_gc_task_manager = NULL; | |
52 | |
53 static void trace_gen_sizes(const char* const str, | |
54 size_t pg_min, size_t pg_max, | |
55 size_t og_min, size_t og_max, | |
56 size_t yg_min, size_t yg_max) | |
57 { | |
58 if (TracePageSizes) { | |
59 tty->print_cr("%s: " SIZE_FORMAT "," SIZE_FORMAT " " | |
60 SIZE_FORMAT "," SIZE_FORMAT " " | |
61 SIZE_FORMAT "," SIZE_FORMAT " " | |
62 SIZE_FORMAT, | |
63 str, pg_min / K, pg_max / K, | |
64 og_min / K, og_max / K, | |
65 yg_min / K, yg_max / K, | |
66 (pg_max + og_max + yg_max) / K); | |
67 } | |
68 } | |
69 | |
70 jint ParallelScavengeHeap::initialize() { | |
1166 | 71 CollectedHeap::pre_initialize(); |
72 | |
0 | 73 // Cannot be initialized until after the flags are parsed |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
74 // GenerationSizer flag_parser; |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
75 _collector_policy = new GenerationSizer(); |
0 | 76 |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
77 size_t yg_min_size = _collector_policy->min_young_gen_size(); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
78 size_t yg_max_size = _collector_policy->max_young_gen_size(); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
79 size_t og_min_size = _collector_policy->min_old_gen_size(); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
80 size_t og_max_size = _collector_policy->max_old_gen_size(); |
0 | 81 // Why isn't there a min_perm_gen_size()? |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
82 size_t pg_min_size = _collector_policy->perm_gen_size(); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
83 size_t pg_max_size = _collector_policy->max_perm_gen_size(); |
0 | 84 |
85 trace_gen_sizes("ps heap raw", | |
86 pg_min_size, pg_max_size, | |
87 og_min_size, og_max_size, | |
88 yg_min_size, yg_max_size); | |
89 | |
90 // The ReservedSpace ctor used below requires that the page size for the perm | |
91 // gen is <= the page size for the rest of the heap (young + old gens). | |
92 const size_t og_page_sz = os::page_size_for_region(yg_min_size + og_min_size, | |
93 yg_max_size + og_max_size, | |
94 8); | |
95 const size_t pg_page_sz = MIN2(os::page_size_for_region(pg_min_size, | |
96 pg_max_size, 16), | |
97 og_page_sz); | |
98 | |
99 const size_t pg_align = set_alignment(_perm_gen_alignment, pg_page_sz); | |
100 const size_t og_align = set_alignment(_old_gen_alignment, og_page_sz); | |
101 const size_t yg_align = set_alignment(_young_gen_alignment, og_page_sz); | |
102 | |
103 // Update sizes to reflect the selected page size(s). | |
104 // | |
105 // NEEDS_CLEANUP. The default TwoGenerationCollectorPolicy uses NewRatio; it | |
106 // should check UseAdaptiveSizePolicy. Changes from generationSizer could | |
107 // move to the common code. | |
108 yg_min_size = align_size_up(yg_min_size, yg_align); | |
109 yg_max_size = align_size_up(yg_max_size, yg_align); | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
110 size_t yg_cur_size = |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
111 align_size_up(_collector_policy->young_gen_size(), yg_align); |
0 | 112 yg_cur_size = MAX2(yg_cur_size, yg_min_size); |
113 | |
114 og_min_size = align_size_up(og_min_size, og_align); | |
2251
336d17dff7cc
7014874: Incorrect COOPs modes on solaris-{sparcv9,amd64} with ParallelGC
kvn
parents:
1972
diff
changeset
|
115 // Align old gen size down to preserve specified heap size. |
336d17dff7cc
7014874: Incorrect COOPs modes on solaris-{sparcv9,amd64} with ParallelGC
kvn
parents:
1972
diff
changeset
|
116 assert(og_align == yg_align, "sanity"); |
336d17dff7cc
7014874: Incorrect COOPs modes on solaris-{sparcv9,amd64} with ParallelGC
kvn
parents:
1972
diff
changeset
|
117 og_max_size = align_size_down(og_max_size, og_align); |
336d17dff7cc
7014874: Incorrect COOPs modes on solaris-{sparcv9,amd64} with ParallelGC
kvn
parents:
1972
diff
changeset
|
118 og_max_size = MAX2(og_max_size, og_min_size); |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
119 size_t og_cur_size = |
2251
336d17dff7cc
7014874: Incorrect COOPs modes on solaris-{sparcv9,amd64} with ParallelGC
kvn
parents:
1972
diff
changeset
|
120 align_size_down(_collector_policy->old_gen_size(), og_align); |
0 | 121 og_cur_size = MAX2(og_cur_size, og_min_size); |
122 | |
123 pg_min_size = align_size_up(pg_min_size, pg_align); | |
124 pg_max_size = align_size_up(pg_max_size, pg_align); | |
125 size_t pg_cur_size = pg_min_size; | |
126 | |
127 trace_gen_sizes("ps heap rnd", | |
128 pg_min_size, pg_max_size, | |
129 og_min_size, og_max_size, | |
130 yg_min_size, yg_max_size); | |
131 | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
132 const size_t total_reserved = pg_max_size + og_max_size + yg_max_size; |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
133 char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
134 |
0 | 135 // The main part of the heap (old gen + young gen) can often use a larger page |
136 // size than is needed or wanted for the perm gen. Use the "compound | |
137 // alignment" ReservedSpace ctor to avoid having to use the same page size for | |
138 // all gens. | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
139 |
237
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
196
diff
changeset
|
140 ReservedHeapSpace heap_rs(pg_max_size, pg_align, og_max_size + yg_max_size, |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
141 og_align, addr); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
142 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
143 if (UseCompressedOops) { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
144 if (addr != NULL && !heap_rs.is_reserved()) { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
145 // Failed to reserve at specified address - the requested memory |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
146 // region is taken already, for example, by 'java' launcher. |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
147 // Try again to reserver heap higher. |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
148 addr = Universe::preferred_heap_base(total_reserved, Universe::ZeroBasedNarrowOop); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
149 ReservedHeapSpace heap_rs0(pg_max_size, pg_align, og_max_size + yg_max_size, |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
150 og_align, addr); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
151 if (addr != NULL && !heap_rs0.is_reserved()) { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
152 // Failed to reserve at specified address again - give up. |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
153 addr = Universe::preferred_heap_base(total_reserved, Universe::HeapBasedNarrowOop); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
154 assert(addr == NULL, ""); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
155 ReservedHeapSpace heap_rs1(pg_max_size, pg_align, og_max_size + yg_max_size, |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
156 og_align, addr); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
157 heap_rs = heap_rs1; |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
158 } else { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
159 heap_rs = heap_rs0; |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
160 } |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
161 } |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
162 } |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
374
diff
changeset
|
163 |
0 | 164 os::trace_page_sizes("ps perm", pg_min_size, pg_max_size, pg_page_sz, |
165 heap_rs.base(), pg_max_size); | |
166 os::trace_page_sizes("ps main", og_min_size + yg_min_size, | |
167 og_max_size + yg_max_size, og_page_sz, | |
168 heap_rs.base() + pg_max_size, | |
169 heap_rs.size() - pg_max_size); | |
170 if (!heap_rs.is_reserved()) { | |
171 vm_shutdown_during_initialization( | |
172 "Could not reserve enough space for object heap"); | |
173 return JNI_ENOMEM; | |
174 } | |
175 | |
176 _reserved = MemRegion((HeapWord*)heap_rs.base(), | |
177 (HeapWord*)(heap_rs.base() + heap_rs.size())); | |
178 | |
179 CardTableExtension* const barrier_set = new CardTableExtension(_reserved, 3); | |
180 _barrier_set = barrier_set; | |
181 oopDesc::set_bs(_barrier_set); | |
182 if (_barrier_set == NULL) { | |
183 vm_shutdown_during_initialization( | |
184 "Could not reserve enough space for barrier set"); | |
185 return JNI_ENOMEM; | |
186 } | |
187 | |
188 // Initial young gen size is 4 Mb | |
189 // | |
190 // XXX - what about flag_parser.young_gen_size()? | |
191 const size_t init_young_size = align_size_up(4 * M, yg_align); | |
192 yg_cur_size = MAX2(MIN2(init_young_size, yg_max_size), yg_cur_size); | |
193 | |
194 // Split the reserved space into perm gen and the main heap (everything else). | |
195 // The main heap uses a different alignment. | |
196 ReservedSpace perm_rs = heap_rs.first_part(pg_max_size); | |
197 ReservedSpace main_rs = heap_rs.last_part(pg_max_size, og_align); | |
198 | |
199 // Make up the generations | |
200 // Calculate the maximum size that a generation can grow. This | |
201 // includes growth into the other generation. Note that the | |
202 // parameter _max_gen_size is kept as the maximum | |
203 // size of the generation as the boundaries currently stand. | |
204 // _max_gen_size is still used as that value. | |
205 double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0; | |
206 double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0; | |
207 | |
208 _gens = new AdjoiningGenerations(main_rs, | |
209 og_cur_size, | |
210 og_min_size, | |
211 og_max_size, | |
212 yg_cur_size, | |
213 yg_min_size, | |
214 yg_max_size, | |
215 yg_align); | |
216 | |
217 _old_gen = _gens->old_gen(); | |
218 _young_gen = _gens->young_gen(); | |
219 | |
220 const size_t eden_capacity = _young_gen->eden_space()->capacity_in_bytes(); | |
221 const size_t old_capacity = _old_gen->capacity_in_bytes(); | |
222 const size_t initial_promo_size = MIN2(eden_capacity, old_capacity); | |
223 _size_policy = | |
224 new PSAdaptiveSizePolicy(eden_capacity, | |
225 initial_promo_size, | |
226 young_gen()->to_space()->capacity_in_bytes(), | |
13
183f41cf8bfe
6557851: CMS: ergonomics defaults are not set with FLAG_SET_ERGO
jmasa
parents:
0
diff
changeset
|
227 intra_heap_alignment(), |
0 | 228 max_gc_pause_sec, |
229 max_gc_minor_pause_sec, | |
230 GCTimeRatio | |
231 ); | |
232 | |
233 _perm_gen = new PSPermGen(perm_rs, | |
234 pg_align, | |
235 pg_cur_size, | |
236 pg_cur_size, | |
237 pg_max_size, | |
238 "perm", 2); | |
239 | |
240 assert(!UseAdaptiveGCBoundary || | |
241 (old_gen()->virtual_space()->high_boundary() == | |
242 young_gen()->virtual_space()->low_boundary()), | |
243 "Boundaries must meet"); | |
244 // initialize the policy counters - 2 collectors, 3 generations | |
245 _gc_policy_counters = | |
246 new PSGCAdaptivePolicyCounters("ParScav:MSC", 2, 3, _size_policy); | |
247 _psh = this; | |
248 | |
249 // Set up the GCTaskManager | |
250 _gc_task_manager = GCTaskManager::create(ParallelGCThreads); | |
251 | |
252 if (UseParallelOldGC && !PSParallelCompact::initialize()) { | |
253 return JNI_ENOMEM; | |
254 } | |
255 | |
256 return JNI_OK; | |
257 } | |
258 | |
259 void ParallelScavengeHeap::post_initialize() { | |
260 // Need to init the tenuring threshold | |
261 PSScavenge::initialize(); | |
262 if (UseParallelOldGC) { | |
263 PSParallelCompact::post_initialize(); | |
264 } else { | |
265 PSMarkSweep::initialize(); | |
266 } | |
267 PSPromotionManager::initialize(); | |
268 } | |
269 | |
270 void ParallelScavengeHeap::update_counters() { | |
271 young_gen()->update_counters(); | |
272 old_gen()->update_counters(); | |
273 perm_gen()->update_counters(); | |
274 } | |
275 | |
276 size_t ParallelScavengeHeap::capacity() const { | |
277 size_t value = young_gen()->capacity_in_bytes() + old_gen()->capacity_in_bytes(); | |
278 return value; | |
279 } | |
280 | |
281 size_t ParallelScavengeHeap::used() const { | |
282 size_t value = young_gen()->used_in_bytes() + old_gen()->used_in_bytes(); | |
283 return value; | |
284 } | |
285 | |
286 bool ParallelScavengeHeap::is_maximal_no_gc() const { | |
287 return old_gen()->is_maximal_no_gc() && young_gen()->is_maximal_no_gc(); | |
288 } | |
289 | |
290 | |
291 size_t ParallelScavengeHeap::permanent_capacity() const { | |
292 return perm_gen()->capacity_in_bytes(); | |
293 } | |
294 | |
295 size_t ParallelScavengeHeap::permanent_used() const { | |
296 return perm_gen()->used_in_bytes(); | |
297 } | |
298 | |
299 size_t ParallelScavengeHeap::max_capacity() const { | |
300 size_t estimated = reserved_region().byte_size(); | |
301 estimated -= perm_gen()->reserved().byte_size(); | |
302 if (UseAdaptiveSizePolicy) { | |
303 estimated -= _size_policy->max_survivor_size(young_gen()->max_size()); | |
304 } else { | |
305 estimated -= young_gen()->to_space()->capacity_in_bytes(); | |
306 } | |
307 return MAX2(estimated, capacity()); | |
308 } | |
309 | |
310 bool ParallelScavengeHeap::is_in(const void* p) const { | |
311 if (young_gen()->is_in(p)) { | |
312 return true; | |
313 } | |
314 | |
315 if (old_gen()->is_in(p)) { | |
316 return true; | |
317 } | |
318 | |
319 if (perm_gen()->is_in(p)) { | |
320 return true; | |
321 } | |
322 | |
323 return false; | |
324 } | |
325 | |
326 bool ParallelScavengeHeap::is_in_reserved(const void* p) const { | |
327 if (young_gen()->is_in_reserved(p)) { | |
328 return true; | |
329 } | |
330 | |
331 if (old_gen()->is_in_reserved(p)) { | |
332 return true; | |
333 } | |
334 | |
335 if (perm_gen()->is_in_reserved(p)) { | |
336 return true; | |
337 } | |
338 | |
339 return false; | |
340 } | |
341 | |
3377
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2251
diff
changeset
|
342 bool ParallelScavengeHeap::is_scavengable(const void* addr) { |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2251
diff
changeset
|
343 return is_in_young((oop)addr); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2251
diff
changeset
|
344 } |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2251
diff
changeset
|
345 |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2251
diff
changeset
|
346 #ifdef ASSERT |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2251
diff
changeset
|
347 // Don't implement this by using is_in_young(). This method is used |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2251
diff
changeset
|
348 // in some cases to check that is_in_young() is correct. |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2251
diff
changeset
|
349 bool ParallelScavengeHeap::is_in_partial_collection(const void *p) { |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2251
diff
changeset
|
350 assert(is_in_reserved(p) || p == NULL, |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2251
diff
changeset
|
351 "Does not work if address is non-null and outside of the heap"); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2251
diff
changeset
|
352 // The order of the generations is perm (low addr), old, young (high addr) |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2251
diff
changeset
|
353 return p >= old_gen()->reserved().end(); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2251
diff
changeset
|
354 } |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2251
diff
changeset
|
355 #endif |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
2251
diff
changeset
|
356 |
0 | 357 // There are two levels of allocation policy here. |
358 // | |
359 // When an allocation request fails, the requesting thread must invoke a VM | |
360 // operation, transfer control to the VM thread, and await the results of a | |
361 // garbage collection. That is quite expensive, and we should avoid doing it | |
362 // multiple times if possible. | |
363 // | |
364 // To accomplish this, we have a basic allocation policy, and also a | |
365 // failed allocation policy. | |
366 // | |
367 // The basic allocation policy controls how you allocate memory without | |
368 // attempting garbage collection. It is okay to grab locks and | |
369 // expand the heap, if that can be done without coming to a safepoint. | |
370 // It is likely that the basic allocation policy will not be very | |
371 // aggressive. | |
372 // | |
373 // The failed allocation policy is invoked from the VM thread after | |
374 // the basic allocation policy is unable to satisfy a mem_allocate | |
375 // request. This policy needs to cover the entire range of collection, | |
376 // heap expansion, and out-of-memory conditions. It should make every | |
377 // attempt to allocate the requested memory. | |
378 | |
379 // Basic allocation policy. Should never be called at a safepoint, or | |
380 // from the VM thread. | |
381 // | |
382 // This method must handle cases where many mem_allocate requests fail | |
383 // simultaneously. When that happens, only one VM operation will succeed, | |
384 // and the rest will not be executed. For that reason, this method loops | |
385 // during failed allocation attempts. If the java heap becomes exhausted, | |
386 // we rely on the size_policy object to force a bail out. | |
387 HeapWord* ParallelScavengeHeap::mem_allocate( | |
388 size_t size, | |
389 bool is_noref, | |
390 bool is_tlab, | |
391 bool* gc_overhead_limit_was_exceeded) { | |
392 assert(!SafepointSynchronize::is_at_safepoint(), "should not be at safepoint"); | |
393 assert(Thread::current() != (Thread*)VMThread::vm_thread(), "should not be in vm thread"); | |
394 assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock"); | |
395 | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
396 // In general gc_overhead_limit_was_exceeded should be false so |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
397 // set it so here and reset it to true only if the gc time |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
398 // limit is being exceeded as checked below. |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
399 *gc_overhead_limit_was_exceeded = false; |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
400 |
0 | 401 HeapWord* result = young_gen()->allocate(size, is_tlab); |
402 | |
403 uint loop_count = 0; | |
404 uint gc_count = 0; | |
405 | |
406 while (result == NULL) { | |
407 // We don't want to have multiple collections for a single filled generation. | |
408 // To prevent this, each thread tracks the total_collections() value, and if | |
409 // the count has changed, does not do a new collection. | |
410 // | |
411 // The collection count must be read only while holding the heap lock. VM | |
412 // operations also hold the heap lock during collections. There is a lock | |
413 // contention case where thread A blocks waiting on the Heap_lock, while | |
414 // thread B is holding it doing a collection. When thread A gets the lock, | |
415 // the collection count has already changed. To prevent duplicate collections, | |
416 // The policy MUST attempt allocations during the same period it reads the | |
417 // total_collections() value! | |
418 { | |
419 MutexLocker ml(Heap_lock); | |
420 gc_count = Universe::heap()->total_collections(); | |
421 | |
422 result = young_gen()->allocate(size, is_tlab); | |
423 | |
424 // (1) If the requested object is too large to easily fit in the | |
425 // young_gen, or | |
426 // (2) If GC is locked out via GCLocker, young gen is full and | |
427 // the need for a GC already signalled to GCLocker (done | |
428 // at a safepoint), | |
429 // ... then, rather than force a safepoint and (a potentially futile) | |
430 // collection (attempt) for each allocation, try allocation directly | |
431 // in old_gen. For case (2) above, we may in the future allow | |
432 // TLAB allocation directly in the old gen. | |
433 if (result != NULL) { | |
434 return result; | |
435 } | |
436 if (!is_tlab && | |
373
06df86c2ec37
6740923: NUMA allocator: Ensure the progress of adaptive chunk resizing
iveresov
parents:
269
diff
changeset
|
437 size >= (young_gen()->eden_space()->capacity_in_words(Thread::current()) / 2)) { |
0 | 438 result = old_gen()->allocate(size, is_tlab); |
439 if (result != NULL) { | |
440 return result; | |
441 } | |
442 } | |
443 if (GC_locker::is_active_and_needs_gc()) { | |
444 // GC is locked out. If this is a TLAB allocation, | |
445 // return NULL; the requestor will retry allocation | |
446 // of an idividual object at a time. | |
447 if (is_tlab) { | |
448 return NULL; | |
449 } | |
450 | |
451 // If this thread is not in a jni critical section, we stall | |
452 // the requestor until the critical section has cleared and | |
453 // GC allowed. When the critical section clears, a GC is | |
454 // initiated by the last thread exiting the critical section; so | |
455 // we retry the allocation sequence from the beginning of the loop, | |
456 // rather than causing more, now probably unnecessary, GC attempts. | |
457 JavaThread* jthr = JavaThread::current(); | |
458 if (!jthr->in_critical()) { | |
459 MutexUnlocker mul(Heap_lock); | |
460 GC_locker::stall_until_clear(); | |
461 continue; | |
462 } else { | |
463 if (CheckJNICalls) { | |
464 fatal("Possible deadlock due to allocating while" | |
465 " in jni critical section"); | |
466 } | |
467 return NULL; | |
468 } | |
469 } | |
470 } | |
471 | |
472 if (result == NULL) { | |
473 | |
474 // Generate a VM operation | |
475 VM_ParallelGCFailedAllocation op(size, is_tlab, gc_count); | |
476 VMThread::execute(&op); | |
477 | |
478 // Did the VM operation execute? If so, return the result directly. | |
479 // This prevents us from looping until time out on requests that can | |
480 // not be satisfied. | |
481 if (op.prologue_succeeded()) { | |
482 assert(Universe::heap()->is_in_or_null(op.result()), | |
483 "result not in heap"); | |
484 | |
485 // If GC was locked out during VM operation then retry allocation | |
486 // and/or stall as necessary. | |
487 if (op.gc_locked()) { | |
488 assert(op.result() == NULL, "must be NULL if gc_locked() is true"); | |
489 continue; // retry and/or stall as necessary | |
490 } | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
491 |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
492 // Exit the loop if the gc time limit has been exceeded. |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
493 // The allocation must have failed above ("result" guarding |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
494 // this path is NULL) and the most recent collection has exceeded the |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
495 // gc overhead limit (although enough may have been collected to |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
496 // satisfy the allocation). Exit the loop so that an out-of-memory |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
497 // will be thrown (return a NULL ignoring the contents of |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
498 // op.result()), |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
499 // but clear gc_overhead_limit_exceeded so that the next collection |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
500 // starts with a clean slate (i.e., forgets about previous overhead |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
501 // excesses). Fill op.result() with a filler object so that the |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
502 // heap remains parsable. |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
503 const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded(); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
504 const bool softrefs_clear = collector_policy()->all_soft_refs_clear(); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
505 assert(!limit_exceeded || softrefs_clear, "Should have been cleared"); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
506 if (limit_exceeded && softrefs_clear) { |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
507 *gc_overhead_limit_was_exceeded = true; |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
508 size_policy()->set_gc_overhead_limit_exceeded(false); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
509 if (PrintGCDetails && Verbose) { |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
510 gclog_or_tty->print_cr("ParallelScavengeHeap::mem_allocate: " |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
511 "return NULL because gc_overhead_limit_exceeded is set"); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
512 } |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
513 if (op.result() != NULL) { |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
514 CollectedHeap::fill_with_object(op.result(), size); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
515 } |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
516 return NULL; |
0 | 517 } |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
518 |
0 | 519 return op.result(); |
520 } | |
521 } | |
522 | |
523 // The policy object will prevent us from looping forever. If the | |
524 // time spent in gc crosses a threshold, we will bail out. | |
525 loop_count++; | |
526 if ((result == NULL) && (QueuedAllocationWarningCount > 0) && | |
527 (loop_count % QueuedAllocationWarningCount == 0)) { | |
528 warning("ParallelScavengeHeap::mem_allocate retries %d times \n\t" | |
529 " size=%d %s", loop_count, size, is_tlab ? "(TLAB)" : ""); | |
530 } | |
531 } | |
532 | |
533 return result; | |
534 } | |
535 | |
536 // Failed allocation policy. Must be called from the VM thread, and | |
537 // only at a safepoint! Note that this method has policy for allocation | |
538 // flow, and NOT collection policy. So we do not check for gc collection | |
539 // time over limit here, that is the responsibility of the heap specific | |
540 // collection methods. This method decides where to attempt allocations, | |
541 // and when to attempt collections, but no collection specific policy. | |
542 HeapWord* ParallelScavengeHeap::failed_mem_allocate(size_t size, bool is_tlab) { | |
543 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); | |
544 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); | |
545 assert(!Universe::heap()->is_gc_active(), "not reentrant"); | |
546 assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock"); | |
547 | |
548 size_t mark_sweep_invocation_count = total_invocations(); | |
549 | |
550 // We assume (and assert!) that an allocation at this point will fail | |
551 // unless we collect. | |
552 | |
553 // First level allocation failure, scavenge and allocate in young gen. | |
554 GCCauseSetter gccs(this, GCCause::_allocation_failure); | |
555 PSScavenge::invoke(); | |
556 HeapWord* result = young_gen()->allocate(size, is_tlab); | |
557 | |
558 // Second level allocation failure. | |
559 // Mark sweep and allocate in young generation. | |
560 if (result == NULL) { | |
561 // There is some chance the scavenge method decided to invoke mark_sweep. | |
562 // Don't mark sweep twice if so. | |
563 if (mark_sweep_invocation_count == total_invocations()) { | |
564 invoke_full_gc(false); | |
565 result = young_gen()->allocate(size, is_tlab); | |
566 } | |
567 } | |
568 | |
569 // Third level allocation failure. | |
570 // After mark sweep and young generation allocation failure, | |
571 // allocate in old generation. | |
572 if (result == NULL && !is_tlab) { | |
573 result = old_gen()->allocate(size, is_tlab); | |
574 } | |
575 | |
576 // Fourth level allocation failure. We're running out of memory. | |
577 // More complete mark sweep and allocate in young generation. | |
578 if (result == NULL) { | |
579 invoke_full_gc(true); | |
580 result = young_gen()->allocate(size, is_tlab); | |
581 } | |
582 | |
583 // Fifth level allocation failure. | |
584 // After more complete mark sweep, allocate in old generation. | |
585 if (result == NULL && !is_tlab) { | |
586 result = old_gen()->allocate(size, is_tlab); | |
587 } | |
588 | |
589 return result; | |
590 } | |
591 | |
592 // | |
593 // This is the policy loop for allocating in the permanent generation. | |
594 // If the initial allocation fails, we create a vm operation which will | |
595 // cause a collection. | |
596 HeapWord* ParallelScavengeHeap::permanent_mem_allocate(size_t size) { | |
597 assert(!SafepointSynchronize::is_at_safepoint(), "should not be at safepoint"); | |
598 assert(Thread::current() != (Thread*)VMThread::vm_thread(), "should not be in vm thread"); | |
599 assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock"); | |
600 | |
601 HeapWord* result; | |
602 | |
603 uint loop_count = 0; | |
604 uint gc_count = 0; | |
605 uint full_gc_count = 0; | |
606 | |
607 do { | |
608 // We don't want to have multiple collections for a single filled generation. | |
609 // To prevent this, each thread tracks the total_collections() value, and if | |
610 // the count has changed, does not do a new collection. | |
611 // | |
612 // The collection count must be read only while holding the heap lock. VM | |
613 // operations also hold the heap lock during collections. There is a lock | |
614 // contention case where thread A blocks waiting on the Heap_lock, while | |
615 // thread B is holding it doing a collection. When thread A gets the lock, | |
616 // the collection count has already changed. To prevent duplicate collections, | |
617 // The policy MUST attempt allocations during the same period it reads the | |
618 // total_collections() value! | |
619 { | |
620 MutexLocker ml(Heap_lock); | |
621 gc_count = Universe::heap()->total_collections(); | |
622 full_gc_count = Universe::heap()->total_full_collections(); | |
623 | |
624 result = perm_gen()->allocate_permanent(size); | |
139
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
625 |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
626 if (result != NULL) { |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
627 return result; |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
628 } |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
629 |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
630 if (GC_locker::is_active_and_needs_gc()) { |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
631 // If this thread is not in a jni critical section, we stall |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
632 // the requestor until the critical section has cleared and |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
633 // GC allowed. When the critical section clears, a GC is |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
634 // initiated by the last thread exiting the critical section; so |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
635 // we retry the allocation sequence from the beginning of the loop, |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
636 // rather than causing more, now probably unnecessary, GC attempts. |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
637 JavaThread* jthr = JavaThread::current(); |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
638 if (!jthr->in_critical()) { |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
639 MutexUnlocker mul(Heap_lock); |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
640 GC_locker::stall_until_clear(); |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
641 continue; |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
642 } else { |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
643 if (CheckJNICalls) { |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
644 fatal("Possible deadlock due to allocating while" |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
645 " in jni critical section"); |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
646 } |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
647 return NULL; |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
648 } |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
649 } |
0 | 650 } |
651 | |
652 if (result == NULL) { | |
653 | |
654 // Exit the loop if the gc time limit has been exceeded. | |
655 // The allocation must have failed above (result must be NULL), | |
656 // and the most recent collection must have exceeded the | |
657 // gc time limit. Exit the loop so that an out-of-memory | |
658 // will be thrown (returning a NULL will do that), but | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
659 // clear gc_overhead_limit_exceeded so that the next collection |
0 | 660 // will succeeded if the applications decides to handle the |
661 // out-of-memory and tries to go on. | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
662 const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded(); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
663 if (limit_exceeded) { |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
664 size_policy()->set_gc_overhead_limit_exceeded(false); |
0 | 665 if (PrintGCDetails && Verbose) { |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
666 gclog_or_tty->print_cr("ParallelScavengeHeap::permanent_mem_allocate:" |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
667 " return NULL because gc_overhead_limit_exceeded is set"); |
0 | 668 } |
669 assert(result == NULL, "Allocation did not fail"); | |
670 return NULL; | |
671 } | |
672 | |
673 // Generate a VM operation | |
674 VM_ParallelGCFailedPermanentAllocation op(size, gc_count, full_gc_count); | |
675 VMThread::execute(&op); | |
676 | |
677 // Did the VM operation execute? If so, return the result directly. | |
678 // This prevents us from looping until time out on requests that can | |
679 // not be satisfied. | |
680 if (op.prologue_succeeded()) { | |
681 assert(Universe::heap()->is_in_permanent_or_null(op.result()), | |
682 "result not in heap"); | |
139
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
683 // If GC was locked out during VM operation then retry allocation |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
684 // and/or stall as necessary. |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
685 if (op.gc_locked()) { |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
686 assert(op.result() == NULL, "must be NULL if gc_locked() is true"); |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
687 continue; // retry and/or stall as necessary |
c0492d52d55b
6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents:
13
diff
changeset
|
688 } |
0 | 689 // If a NULL results is being returned, an out-of-memory |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
690 // will be thrown now. Clear the gc_overhead_limit_exceeded |
0 | 691 // flag to avoid the following situation. |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
692 // gc_overhead_limit_exceeded is set during a collection |
0 | 693 // the collection fails to return enough space and an OOM is thrown |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
694 // a subsequent GC prematurely throws an out-of-memory because |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
695 // the gc_overhead_limit_exceeded counts did not start |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
696 // again from 0. |
0 | 697 if (op.result() == NULL) { |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1166
diff
changeset
|
698 size_policy()->reset_gc_overhead_limit_count(); |
0 | 699 } |
700 return op.result(); | |
701 } | |
702 } | |
703 | |
704 // The policy object will prevent us from looping forever. If the | |
705 // time spent in gc crosses a threshold, we will bail out. | |
706 loop_count++; | |
707 if ((QueuedAllocationWarningCount > 0) && | |
708 (loop_count % QueuedAllocationWarningCount == 0)) { | |
709 warning("ParallelScavengeHeap::permanent_mem_allocate retries %d times \n\t" | |
710 " size=%d", loop_count, size); | |
711 } | |
712 } while (result == NULL); | |
713 | |
714 return result; | |
715 } | |
716 | |
717 // | |
718 // This is the policy code for permanent allocations which have failed | |
719 // and require a collection. Note that just as in failed_mem_allocate, | |
720 // we do not set collection policy, only where & when to allocate and | |
721 // collect. | |
722 HeapWord* ParallelScavengeHeap::failed_permanent_mem_allocate(size_t size) { | |
723 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); | |
724 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); | |
725 assert(!Universe::heap()->is_gc_active(), "not reentrant"); | |
726 assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock"); | |
727 assert(size > perm_gen()->free_in_words(), "Allocation should fail"); | |
728 | |
729 // We assume (and assert!) that an allocation at this point will fail | |
730 // unless we collect. | |
731 | |
732 // First level allocation failure. Mark-sweep and allocate in perm gen. | |
733 GCCauseSetter gccs(this, GCCause::_allocation_failure); | |
734 invoke_full_gc(false); | |
735 HeapWord* result = perm_gen()->allocate_permanent(size); | |
736 | |
737 // Second level allocation failure. We're running out of memory. | |
738 if (result == NULL) { | |
739 invoke_full_gc(true); | |
740 result = perm_gen()->allocate_permanent(size); | |
741 } | |
742 | |
743 return result; | |
744 } | |
745 | |
746 void ParallelScavengeHeap::ensure_parsability(bool retire_tlabs) { | |
747 CollectedHeap::ensure_parsability(retire_tlabs); | |
748 young_gen()->eden_space()->ensure_parsability(); | |
749 } | |
750 | |
751 size_t ParallelScavengeHeap::unsafe_max_alloc() { | |
752 return young_gen()->eden_space()->free_in_bytes(); | |
753 } | |
754 | |
755 size_t ParallelScavengeHeap::tlab_capacity(Thread* thr) const { | |
756 return young_gen()->eden_space()->tlab_capacity(thr); | |
757 } | |
758 | |
759 size_t ParallelScavengeHeap::unsafe_max_tlab_alloc(Thread* thr) const { | |
760 return young_gen()->eden_space()->unsafe_max_tlab_alloc(thr); | |
761 } | |
762 | |
763 HeapWord* ParallelScavengeHeap::allocate_new_tlab(size_t size) { | |
764 return young_gen()->allocate(size, true); | |
765 } | |
766 | |
767 void ParallelScavengeHeap::accumulate_statistics_all_tlabs() { | |
768 CollectedHeap::accumulate_statistics_all_tlabs(); | |
769 } | |
770 | |
771 void ParallelScavengeHeap::resize_all_tlabs() { | |
772 CollectedHeap::resize_all_tlabs(); | |
773 } | |
774 | |
1027
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
989
diff
changeset
|
775 bool ParallelScavengeHeap::can_elide_initializing_store_barrier(oop new_obj) { |
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
989
diff
changeset
|
776 // We don't need barriers for stores to objects in the |
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
989
diff
changeset
|
777 // young gen and, a fortiori, for initializing stores to |
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
989
diff
changeset
|
778 // objects therein. |
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
989
diff
changeset
|
779 return is_in_young(new_obj); |
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
989
diff
changeset
|
780 } |
39b01ab7035a
6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents:
989
diff
changeset
|
781 |
0 | 782 // This method is used by System.gc() and JVMTI. |
783 void ParallelScavengeHeap::collect(GCCause::Cause cause) { | |
784 assert(!Heap_lock->owned_by_self(), | |
785 "this thread should not own the Heap_lock"); | |
786 | |
787 unsigned int gc_count = 0; | |
788 unsigned int full_gc_count = 0; | |
789 { | |
790 MutexLocker ml(Heap_lock); | |
791 // This value is guarded by the Heap_lock | |
792 gc_count = Universe::heap()->total_collections(); | |
793 full_gc_count = Universe::heap()->total_full_collections(); | |
794 } | |
795 | |
796 VM_ParallelGCSystemGC op(gc_count, full_gc_count, cause); | |
797 VMThread::execute(&op); | |
798 } | |
799 | |
800 // This interface assumes that it's being called by the | |
801 // vm thread. It collects the heap assuming that the | |
802 // heap lock is already held and that we are executing in | |
803 // the context of the vm thread. | |
804 void ParallelScavengeHeap::collect_as_vm_thread(GCCause::Cause cause) { | |
805 assert(Thread::current()->is_VM_thread(), "Precondition#1"); | |
806 assert(Heap_lock->is_locked(), "Precondition#2"); | |
807 GCCauseSetter gcs(this, cause); | |
808 switch (cause) { | |
809 case GCCause::_heap_inspection: | |
810 case GCCause::_heap_dump: { | |
811 HandleMark hm; | |
812 invoke_full_gc(false); | |
813 break; | |
814 } | |
815 default: // XXX FIX ME | |
816 ShouldNotReachHere(); | |
817 } | |
818 } | |
819 | |
820 | |
821 void ParallelScavengeHeap::oop_iterate(OopClosure* cl) { | |
822 Unimplemented(); | |
823 } | |
824 | |
825 void ParallelScavengeHeap::object_iterate(ObjectClosure* cl) { | |
826 young_gen()->object_iterate(cl); | |
827 old_gen()->object_iterate(cl); | |
828 perm_gen()->object_iterate(cl); | |
829 } | |
830 | |
831 void ParallelScavengeHeap::permanent_oop_iterate(OopClosure* cl) { | |
832 Unimplemented(); | |
833 } | |
834 | |
835 void ParallelScavengeHeap::permanent_object_iterate(ObjectClosure* cl) { | |
836 perm_gen()->object_iterate(cl); | |
837 } | |
838 | |
839 HeapWord* ParallelScavengeHeap::block_start(const void* addr) const { | |
840 if (young_gen()->is_in_reserved(addr)) { | |
841 assert(young_gen()->is_in(addr), | |
842 "addr should be in allocated part of young gen"); | |
1907 | 843 // called from os::print_location by find or VMError |
844 if (Debugging || VMError::fatal_error_in_progress()) return NULL; | |
0 | 845 Unimplemented(); |
846 } else if (old_gen()->is_in_reserved(addr)) { | |
847 assert(old_gen()->is_in(addr), | |
848 "addr should be in allocated part of old gen"); | |
849 return old_gen()->start_array()->object_start((HeapWord*)addr); | |
850 } else if (perm_gen()->is_in_reserved(addr)) { | |
851 assert(perm_gen()->is_in(addr), | |
852 "addr should be in allocated part of perm gen"); | |
853 return perm_gen()->start_array()->object_start((HeapWord*)addr); | |
854 } | |
855 return 0; | |
856 } | |
857 | |
858 size_t ParallelScavengeHeap::block_size(const HeapWord* addr) const { | |
859 return oop(addr)->size(); | |
860 } | |
861 | |
862 bool ParallelScavengeHeap::block_is_obj(const HeapWord* addr) const { | |
863 return block_start(addr) == addr; | |
864 } | |
865 | |
866 jlong ParallelScavengeHeap::millis_since_last_gc() { | |
867 return UseParallelOldGC ? | |
868 PSParallelCompact::millis_since_last_gc() : | |
869 PSMarkSweep::millis_since_last_gc(); | |
870 } | |
871 | |
872 void ParallelScavengeHeap::prepare_for_verify() { | |
873 ensure_parsability(false); // no need to retire TLABs for verification | |
874 } | |
875 | |
876 void ParallelScavengeHeap::print() const { print_on(tty); } | |
877 | |
878 void ParallelScavengeHeap::print_on(outputStream* st) const { | |
879 young_gen()->print_on(st); | |
880 old_gen()->print_on(st); | |
881 perm_gen()->print_on(st); | |
882 } | |
883 | |
884 void ParallelScavengeHeap::gc_threads_do(ThreadClosure* tc) const { | |
885 PSScavenge::gc_task_manager()->threads_do(tc); | |
886 } | |
887 | |
888 void ParallelScavengeHeap::print_gc_threads_on(outputStream* st) const { | |
889 PSScavenge::gc_task_manager()->print_threads_on(st); | |
890 } | |
891 | |
892 void ParallelScavengeHeap::print_tracing_info() const { | |
893 if (TraceGen0Time) { | |
894 double time = PSScavenge::accumulated_time()->seconds(); | |
895 tty->print_cr("[Accumulated GC generation 0 time %3.7f secs]", time); | |
896 } | |
897 if (TraceGen1Time) { | |
898 double time = PSMarkSweep::accumulated_time()->seconds(); | |
899 tty->print_cr("[Accumulated GC generation 1 time %3.7f secs]", time); | |
900 } | |
901 } | |
902 | |
903 | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3377
diff
changeset
|
904 void ParallelScavengeHeap::verify(bool allow_dirty, bool silent, VerifyOption option /* ignored */) { |
0 | 905 // Why do we need the total_collections()-filter below? |
906 if (total_collections() > 0) { | |
907 if (!silent) { | |
908 gclog_or_tty->print("permanent "); | |
909 } | |
910 perm_gen()->verify(allow_dirty); | |
911 | |
912 if (!silent) { | |
913 gclog_or_tty->print("tenured "); | |
914 } | |
915 old_gen()->verify(allow_dirty); | |
916 | |
917 if (!silent) { | |
918 gclog_or_tty->print("eden "); | |
919 } | |
920 young_gen()->verify(allow_dirty); | |
921 } | |
922 if (!silent) { | |
923 gclog_or_tty->print("ref_proc "); | |
924 } | |
925 ReferenceProcessor::verify(); | |
926 } | |
927 | |
928 void ParallelScavengeHeap::print_heap_change(size_t prev_used) { | |
929 if (PrintGCDetails && Verbose) { | |
930 gclog_or_tty->print(" " SIZE_FORMAT | |
931 "->" SIZE_FORMAT | |
932 "(" SIZE_FORMAT ")", | |
933 prev_used, used(), capacity()); | |
934 } else { | |
935 gclog_or_tty->print(" " SIZE_FORMAT "K" | |
936 "->" SIZE_FORMAT "K" | |
937 "(" SIZE_FORMAT "K)", | |
938 prev_used / K, used() / K, capacity() / K); | |
939 } | |
940 } | |
941 | |
942 ParallelScavengeHeap* ParallelScavengeHeap::heap() { | |
943 assert(_psh != NULL, "Uninitialized access to ParallelScavengeHeap::heap()"); | |
944 assert(_psh->kind() == CollectedHeap::ParallelScavengeHeap, "not a parallel scavenge heap"); | |
945 return _psh; | |
946 } | |
947 | |
948 // Before delegating the resize to the young generation, | |
949 // the reserved space for the young and old generations | |
950 // may be changed to accomodate the desired resize. | |
951 void ParallelScavengeHeap::resize_young_gen(size_t eden_size, | |
952 size_t survivor_size) { | |
953 if (UseAdaptiveGCBoundary) { | |
954 if (size_policy()->bytes_absorbed_from_eden() != 0) { | |
955 size_policy()->reset_bytes_absorbed_from_eden(); | |
956 return; // The generation changed size already. | |
957 } | |
958 gens()->adjust_boundary_for_young_gen_needs(eden_size, survivor_size); | |
959 } | |
960 | |
961 // Delegate the resize to the generation. | |
962 _young_gen->resize(eden_size, survivor_size); | |
963 } | |
964 | |
965 // Before delegating the resize to the old generation, | |
966 // the reserved space for the young and old generations | |
967 // may be changed to accomodate the desired resize. | |
968 void ParallelScavengeHeap::resize_old_gen(size_t desired_free_space) { | |
969 if (UseAdaptiveGCBoundary) { | |
970 if (size_policy()->bytes_absorbed_from_eden() != 0) { | |
971 size_policy()->reset_bytes_absorbed_from_eden(); | |
972 return; // The generation changed size already. | |
973 } | |
974 gens()->adjust_boundary_for_old_gen_needs(desired_free_space); | |
975 } | |
976 | |
977 // Delegate the resize to the generation. | |
978 _old_gen->resize(desired_free_space); | |
979 } | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
980 |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
845
diff
changeset
|
981 ParallelScavengeHeap::ParStrongRootsScope::ParStrongRootsScope() { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
845
diff
changeset
|
982 // nothing particular |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
845
diff
changeset
|
983 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
845
diff
changeset
|
984 |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
845
diff
changeset
|
985 ParallelScavengeHeap::ParStrongRootsScope::~ParStrongRootsScope() { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
845
diff
changeset
|
986 // nothing particular |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
845
diff
changeset
|
987 } |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
845
diff
changeset
|
988 |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
989 #ifndef PRODUCT |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
990 void ParallelScavengeHeap::record_gen_tops_before_GC() { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
991 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
992 young_gen()->record_spaces_top(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
993 old_gen()->record_spaces_top(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
994 perm_gen()->record_spaces_top(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
995 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
996 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
997 |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
998 void ParallelScavengeHeap::gen_mangle_unused_area() { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
999 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
1000 young_gen()->eden_space()->mangle_unused_area(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
1001 young_gen()->to_space()->mangle_unused_area(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
1002 young_gen()->from_space()->mangle_unused_area(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
1003 old_gen()->object_space()->mangle_unused_area(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
1004 perm_gen()->object_space()->mangle_unused_area(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
1005 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
1006 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
139
diff
changeset
|
1007 #endif |