Mercurial > hg > graal-compiler
annotate src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp @ 2149:7e37af9d69ef
7011379: G1: overly long concurrent marking cycles
Summary: This changeset introduces filtering of SATB buffers at the point when they are about to be enqueued. If this filtering clears enough entries on each buffer, the buffer can then be re-used and not enqueued. This cuts down the number of SATB buffers that need to be processed by the concurrent marking threads.
Reviewed-by: johnc, ysr
author | tonyp |
---|---|
date | Wed, 19 Jan 2011 09:35:17 -0500 |
parents | 74ee0db180fa |
children | 92da084fefc9 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1387
diff
changeset
|
2 * Copyright (c) 2002, 2010, 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/cardTableExtension.hpp" | |
27 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" | |
28 #include "gc_implementation/parallelScavenge/generationSizer.hpp" | |
29 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp" | |
30 #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp" | |
31 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp" | |
32 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp" | |
33 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" | |
34 #include "gc_implementation/parallelScavenge/psTasks.hpp" | |
35 #include "gc_implementation/shared/isGCActiveMark.hpp" | |
36 #include "gc_implementation/shared/spaceDecorator.hpp" | |
37 #include "gc_interface/gcCause.hpp" | |
38 #include "memory/collectorPolicy.hpp" | |
39 #include "memory/gcLocker.inline.hpp" | |
40 #include "memory/referencePolicy.hpp" | |
41 #include "memory/referenceProcessor.hpp" | |
42 #include "memory/resourceArea.hpp" | |
43 #include "oops/oop.inline.hpp" | |
44 #include "oops/oop.psgc.inline.hpp" | |
45 #include "runtime/biasedLocking.hpp" | |
46 #include "runtime/fprofiler.hpp" | |
47 #include "runtime/handles.inline.hpp" | |
48 #include "runtime/threadCritical.hpp" | |
49 #include "runtime/vmThread.hpp" | |
50 #include "runtime/vm_operations.hpp" | |
51 #include "services/memoryService.hpp" | |
52 #include "utilities/stack.inline.hpp" | |
0 | 53 |
54 | |
55 HeapWord* PSScavenge::_to_space_top_before_gc = NULL; | |
56 int PSScavenge::_consecutive_skipped_scavenges = 0; | |
57 ReferenceProcessor* PSScavenge::_ref_processor = NULL; | |
58 CardTableExtension* PSScavenge::_card_table = NULL; | |
59 bool PSScavenge::_survivor_overflow = false; | |
60 int PSScavenge::_tenuring_threshold = 0; | |
61 HeapWord* PSScavenge::_young_generation_boundary = NULL; | |
62 elapsedTimer PSScavenge::_accumulated_time; | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
63 Stack<markOop> PSScavenge::_preserved_mark_stack; |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
64 Stack<oop> PSScavenge::_preserved_oop_stack; |
0 | 65 CollectorCounters* PSScavenge::_counters = NULL; |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
66 bool PSScavenge::_promotion_failed = false; |
0 | 67 |
68 // Define before use | |
69 class PSIsAliveClosure: public BoolObjectClosure { | |
70 public: | |
71 void do_object(oop p) { | |
72 assert(false, "Do not call."); | |
73 } | |
74 bool do_object_b(oop p) { | |
75 return (!PSScavenge::is_obj_in_young((HeapWord*) p)) || p->is_forwarded(); | |
76 } | |
77 }; | |
78 | |
79 PSIsAliveClosure PSScavenge::_is_alive_closure; | |
80 | |
81 class PSKeepAliveClosure: public OopClosure { | |
82 protected: | |
83 MutableSpace* _to_space; | |
84 PSPromotionManager* _promotion_manager; | |
85 | |
86 public: | |
87 PSKeepAliveClosure(PSPromotionManager* pm) : _promotion_manager(pm) { | |
88 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
89 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
90 _to_space = heap->young_gen()->to_space(); | |
91 | |
92 assert(_promotion_manager != NULL, "Sanity"); | |
93 } | |
94 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
95 template <class T> void do_oop_work(T* p) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
96 assert (!oopDesc::is_null(*p), "expected non-null ref"); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
97 assert ((oopDesc::load_decode_heap_oop_not_null(p))->is_oop(), |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
98 "expected an oop while scanning weak refs"); |
0 | 99 |
100 // Weak refs may be visited more than once. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
101 if (PSScavenge::should_scavenge(p, _to_space)) { |
0 | 102 PSScavenge::copy_and_push_safe_barrier(_promotion_manager, p); |
103 } | |
104 } | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
105 virtual void do_oop(oop* p) { PSKeepAliveClosure::do_oop_work(p); } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
106 virtual void do_oop(narrowOop* p) { PSKeepAliveClosure::do_oop_work(p); } |
0 | 107 }; |
108 | |
109 class PSEvacuateFollowersClosure: public VoidClosure { | |
110 private: | |
111 PSPromotionManager* _promotion_manager; | |
112 public: | |
113 PSEvacuateFollowersClosure(PSPromotionManager* pm) : _promotion_manager(pm) {} | |
114 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
115 virtual void do_void() { |
0 | 116 assert(_promotion_manager != NULL, "Sanity"); |
117 _promotion_manager->drain_stacks(true); | |
118 guarantee(_promotion_manager->stacks_empty(), | |
119 "stacks should be empty at this point"); | |
120 } | |
121 }; | |
122 | |
123 class PSPromotionFailedClosure : public ObjectClosure { | |
124 virtual void do_object(oop obj) { | |
125 if (obj->is_forwarded()) { | |
126 obj->init_mark(); | |
127 } | |
128 } | |
129 }; | |
130 | |
131 class PSRefProcTaskProxy: public GCTask { | |
132 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask; | |
133 ProcessTask & _rp_task; | |
134 uint _work_id; | |
135 public: | |
136 PSRefProcTaskProxy(ProcessTask & rp_task, uint work_id) | |
137 : _rp_task(rp_task), | |
138 _work_id(work_id) | |
139 { } | |
140 | |
141 private: | |
142 virtual char* name() { return (char *)"Process referents by policy in parallel"; } | |
143 virtual void do_it(GCTaskManager* manager, uint which); | |
144 }; | |
145 | |
146 void PSRefProcTaskProxy::do_it(GCTaskManager* manager, uint which) | |
147 { | |
148 PSPromotionManager* promotion_manager = | |
149 PSPromotionManager::gc_thread_promotion_manager(which); | |
150 assert(promotion_manager != NULL, "sanity check"); | |
151 PSKeepAliveClosure keep_alive(promotion_manager); | |
152 PSEvacuateFollowersClosure evac_followers(promotion_manager); | |
153 PSIsAliveClosure is_alive; | |
154 _rp_task.work(_work_id, is_alive, keep_alive, evac_followers); | |
155 } | |
156 | |
157 class PSRefEnqueueTaskProxy: public GCTask { | |
158 typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask; | |
159 EnqueueTask& _enq_task; | |
160 uint _work_id; | |
161 | |
162 public: | |
163 PSRefEnqueueTaskProxy(EnqueueTask& enq_task, uint work_id) | |
164 : _enq_task(enq_task), | |
165 _work_id(work_id) | |
166 { } | |
167 | |
168 virtual char* name() { return (char *)"Enqueue reference objects in parallel"; } | |
169 virtual void do_it(GCTaskManager* manager, uint which) | |
170 { | |
171 _enq_task.work(_work_id); | |
172 } | |
173 }; | |
174 | |
175 class PSRefProcTaskExecutor: public AbstractRefProcTaskExecutor { | |
176 virtual void execute(ProcessTask& task); | |
177 virtual void execute(EnqueueTask& task); | |
178 }; | |
179 | |
180 void PSRefProcTaskExecutor::execute(ProcessTask& task) | |
181 { | |
182 GCTaskQueue* q = GCTaskQueue::create(); | |
183 for(uint i=0; i<ParallelGCThreads; i++) { | |
184 q->enqueue(new PSRefProcTaskProxy(task, i)); | |
185 } | |
186 ParallelTaskTerminator terminator( | |
1706
9d7a8ab3736b
6962589: remove breadth first scanning code from parallel gc
tonyp
parents:
1638
diff
changeset
|
187 ParallelScavengeHeap::gc_task_manager()->workers(), |
9d7a8ab3736b
6962589: remove breadth first scanning code from parallel gc
tonyp
parents:
1638
diff
changeset
|
188 (TaskQueueSetSuper*) PSPromotionManager::stack_array_depth()); |
0 | 189 if (task.marks_oops_alive() && ParallelGCThreads > 1) { |
190 for (uint j=0; j<ParallelGCThreads; j++) { | |
191 q->enqueue(new StealTask(&terminator)); | |
192 } | |
193 } | |
194 ParallelScavengeHeap::gc_task_manager()->execute_and_wait(q); | |
195 } | |
196 | |
197 | |
198 void PSRefProcTaskExecutor::execute(EnqueueTask& task) | |
199 { | |
200 GCTaskQueue* q = GCTaskQueue::create(); | |
201 for(uint i=0; i<ParallelGCThreads; i++) { | |
202 q->enqueue(new PSRefEnqueueTaskProxy(task, i)); | |
203 } | |
204 ParallelScavengeHeap::gc_task_manager()->execute_and_wait(q); | |
205 } | |
206 | |
207 // This method contains all heap specific policy for invoking scavenge. | |
208 // PSScavenge::invoke_no_policy() will do nothing but attempt to | |
209 // scavenge. It will not clean up after failed promotions, bail out if | |
210 // we've exceeded policy time limits, or any other special behavior. | |
211 // All such policy should be placed here. | |
212 // | |
213 // Note that this method should only be called from the vm_thread while | |
214 // at a safepoint! | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
215 void PSScavenge::invoke() { |
0 | 216 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); |
217 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); | |
218 assert(!Universe::heap()->is_gc_active(), "not reentrant"); | |
219 | |
220 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
221 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
222 | |
223 PSAdaptiveSizePolicy* policy = heap->size_policy(); | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
224 IsGCActiveMark mark; |
0 | 225 |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
226 bool scavenge_was_done = PSScavenge::invoke_no_policy(); |
0 | 227 |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
228 PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters(); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
229 if (UsePerfData) |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
230 counters->update_full_follows_scavenge(0); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
231 if (!scavenge_was_done || |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
232 policy->should_full_GC(heap->old_gen()->free_in_bytes())) { |
0 | 233 if (UsePerfData) |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
234 counters->update_full_follows_scavenge(full_follows_scavenge); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
235 GCCauseSetter gccs(heap, GCCause::_adaptive_size_policy); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
236 CollectorPolicy* cp = heap->collector_policy(); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
237 const bool clear_all_softrefs = cp->should_clear_all_soft_refs(); |
0 | 238 |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
239 if (UseParallelOldGC) { |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
240 PSParallelCompact::invoke_no_policy(clear_all_softrefs); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
241 } else { |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
242 PSMarkSweep::invoke_no_policy(clear_all_softrefs); |
0 | 243 } |
244 } | |
245 } | |
246 | |
247 // This method contains no policy. You should probably | |
248 // be calling invoke() instead. | |
249 bool PSScavenge::invoke_no_policy() { | |
250 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); | |
251 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); | |
252 | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
253 assert(_preserved_mark_stack.is_empty(), "should be empty"); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
254 assert(_preserved_oop_stack.is_empty(), "should be empty"); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
255 |
0 | 256 TimeStamp scavenge_entry; |
257 TimeStamp scavenge_midpoint; | |
258 TimeStamp scavenge_exit; | |
259 | |
260 scavenge_entry.update(); | |
261 | |
262 if (GC_locker::check_active_before_gc()) { | |
263 return false; | |
264 } | |
265 | |
266 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
267 GCCause::Cause gc_cause = heap->gc_cause(); | |
268 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
269 | |
270 // Check for potential problems. | |
271 if (!should_attempt_scavenge()) { | |
272 return false; | |
273 } | |
274 | |
275 bool promotion_failure_occurred = false; | |
276 | |
277 PSYoungGen* young_gen = heap->young_gen(); | |
278 PSOldGen* old_gen = heap->old_gen(); | |
279 PSPermGen* perm_gen = heap->perm_gen(); | |
280 PSAdaptiveSizePolicy* size_policy = heap->size_policy(); | |
281 heap->increment_total_collections(); | |
282 | |
283 AdaptiveSizePolicyOutput(size_policy, heap->total_collections()); | |
284 | |
285 if ((gc_cause != GCCause::_java_lang_system_gc) || | |
286 UseAdaptiveSizePolicyWithSystemGC) { | |
287 // Gather the feedback data for eden occupancy. | |
288 young_gen->eden_space()->accumulate_statistics(); | |
289 } | |
290 | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
291 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
292 // Save information needed to minimize mangling |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
293 heap->record_gen_tops_before_GC(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
294 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
295 |
0 | 296 if (PrintHeapAtGC) { |
297 Universe::print_heap_before_gc(); | |
298 } | |
299 | |
300 assert(!NeverTenure || _tenuring_threshold == markOopDesc::max_age + 1, "Sanity"); | |
301 assert(!AlwaysTenure || _tenuring_threshold == 0, "Sanity"); | |
302 | |
303 size_t prev_used = heap->used(); | |
304 assert(promotion_failed() == false, "Sanity"); | |
305 | |
306 // Fill in TLABs | |
307 heap->accumulate_statistics_all_tlabs(); | |
308 heap->ensure_parsability(true); // retire TLABs | |
309 | |
310 if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) { | |
311 HandleMark hm; // Discard invalid handles created during verification | |
312 gclog_or_tty->print(" VerifyBeforeGC:"); | |
313 Universe::verify(true); | |
314 } | |
315 | |
316 { | |
317 ResourceMark rm; | |
318 HandleMark hm; | |
319 | |
320 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); | |
321 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); | |
322 TraceTime t1("GC", PrintGC, !PrintGCDetails, gclog_or_tty); | |
323 TraceCollectorStats tcs(counters()); | |
324 TraceMemoryManagerStats tms(false /* not full GC */); | |
325 | |
326 if (TraceGen0Time) accumulated_time()->start(); | |
327 | |
328 // Let the size policy know we're starting | |
329 size_policy->minor_collection_begin(); | |
330 | |
331 // Verify the object start arrays. | |
332 if (VerifyObjectStartArray && | |
333 VerifyBeforeGC) { | |
334 old_gen->verify_object_start_array(); | |
335 perm_gen->verify_object_start_array(); | |
336 } | |
337 | |
338 // Verify no unmarked old->young roots | |
339 if (VerifyRememberedSets) { | |
340 CardTableExtension::verify_all_young_refs_imprecise(); | |
341 } | |
342 | |
343 if (!ScavengeWithObjectsInToSpace) { | |
344 assert(young_gen->to_space()->is_empty(), | |
345 "Attempt to scavenge with live objects in to_space"); | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
346 young_gen->to_space()->clear(SpaceDecorator::Mangle); |
0 | 347 } else if (ZapUnusedHeapArea) { |
348 young_gen->to_space()->mangle_unused_area(); | |
349 } | |
350 save_to_space_top_before_gc(); | |
351 | |
352 NOT_PRODUCT(reference_processor()->verify_no_references_recorded()); | |
353 COMPILER2_PRESENT(DerivedPointerTable::clear()); | |
354 | |
355 reference_processor()->enable_discovery(); | |
457
27a80744a83b
6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents:
453
diff
changeset
|
356 reference_processor()->setup_policy(false); |
0 | 357 |
358 // We track how much was promoted to the next generation for | |
359 // the AdaptiveSizePolicy. | |
360 size_t old_gen_used_before = old_gen->used_in_bytes(); | |
361 | |
362 // For PrintGCDetails | |
363 size_t young_gen_used_before = young_gen->used_in_bytes(); | |
364 | |
365 // Reset our survivor overflow. | |
366 set_survivor_overflow(false); | |
367 | |
368 // We need to save the old/perm top values before | |
369 // creating the promotion_manager. We pass the top | |
370 // values to the card_table, to prevent it from | |
371 // straying into the promotion labs. | |
372 HeapWord* old_top = old_gen->object_space()->top(); | |
373 HeapWord* perm_top = perm_gen->object_space()->top(); | |
374 | |
375 // Release all previously held resources | |
376 gc_task_manager()->release_all_resources(); | |
377 | |
378 PSPromotionManager::pre_scavenge(); | |
379 | |
380 // We'll use the promotion manager again later. | |
381 PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager(); | |
382 { | |
383 // TraceTime("Roots"); | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
579
diff
changeset
|
384 ParallelScavengeHeap::ParStrongRootsScope psrs; |
0 | 385 |
386 GCTaskQueue* q = GCTaskQueue::create(); | |
387 | |
388 for(uint i=0; i<ParallelGCThreads; i++) { | |
389 q->enqueue(new OldToYoungRootsTask(old_gen, old_top, i)); | |
390 } | |
391 | |
392 q->enqueue(new SerialOldToYoungRootsTask(perm_gen, perm_top)); | |
393 | |
394 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::universe)); | |
395 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jni_handles)); | |
396 // We scan the thread roots in parallel | |
397 Threads::create_thread_roots_tasks(q); | |
398 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::object_synchronizer)); | |
399 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::flat_profiler)); | |
400 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::management)); | |
401 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary)); | |
402 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti)); | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
579
diff
changeset
|
403 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache)); |
0 | 404 |
405 ParallelTaskTerminator terminator( | |
1706
9d7a8ab3736b
6962589: remove breadth first scanning code from parallel gc
tonyp
parents:
1638
diff
changeset
|
406 gc_task_manager()->workers(), |
9d7a8ab3736b
6962589: remove breadth first scanning code from parallel gc
tonyp
parents:
1638
diff
changeset
|
407 (TaskQueueSetSuper*) promotion_manager->stack_array_depth()); |
0 | 408 if (ParallelGCThreads>1) { |
409 for (uint j=0; j<ParallelGCThreads; j++) { | |
410 q->enqueue(new StealTask(&terminator)); | |
411 } | |
412 } | |
413 | |
414 gc_task_manager()->execute_and_wait(q); | |
415 } | |
416 | |
417 scavenge_midpoint.update(); | |
418 | |
419 // Process reference objects discovered during scavenge | |
420 { | |
457
27a80744a83b
6778647: snap(), snap_policy() should be renamed setup(), setup_policy()
ysr
parents:
453
diff
changeset
|
421 reference_processor()->setup_policy(false); // not always_clear |
0 | 422 PSKeepAliveClosure keep_alive(promotion_manager); |
423 PSEvacuateFollowersClosure evac_followers(promotion_manager); | |
424 if (reference_processor()->processing_is_mt()) { | |
425 PSRefProcTaskExecutor task_executor; | |
426 reference_processor()->process_discovered_references( | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
269
diff
changeset
|
427 &_is_alive_closure, &keep_alive, &evac_followers, &task_executor); |
0 | 428 } else { |
429 reference_processor()->process_discovered_references( | |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
269
diff
changeset
|
430 &_is_alive_closure, &keep_alive, &evac_followers, NULL); |
0 | 431 } |
432 } | |
433 | |
434 // Enqueue reference objects discovered during scavenge. | |
435 if (reference_processor()->processing_is_mt()) { | |
436 PSRefProcTaskExecutor task_executor; | |
437 reference_processor()->enqueue_discovered_references(&task_executor); | |
438 } else { | |
439 reference_processor()->enqueue_discovered_references(NULL); | |
440 } | |
441 | |
442 // Finally, flush the promotion_manager's labs, and deallocate its stacks. | |
443 PSPromotionManager::post_scavenge(); | |
444 | |
445 promotion_failure_occurred = promotion_failed(); | |
446 if (promotion_failure_occurred) { | |
447 clean_up_failed_promotion(); | |
448 if (PrintGC) { | |
449 gclog_or_tty->print("--"); | |
450 } | |
451 } | |
452 | |
453 // Let the size policy know we're done. Note that we count promotion | |
454 // failure cleanup time as part of the collection (otherwise, we're | |
455 // implicitly saying it's mutator time). | |
456 size_policy->minor_collection_end(gc_cause); | |
457 | |
458 if (!promotion_failure_occurred) { | |
459 // Swap the survivor spaces. | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
460 |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
461 |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
462 young_gen->eden_space()->clear(SpaceDecorator::Mangle); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
463 young_gen->from_space()->clear(SpaceDecorator::Mangle); |
0 | 464 young_gen->swap_spaces(); |
465 | |
466 size_t survived = young_gen->from_space()->used_in_bytes(); | |
467 size_t promoted = old_gen->used_in_bytes() - old_gen_used_before; | |
468 size_policy->update_averages(_survivor_overflow, survived, promoted); | |
469 | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
470 // A successful scavenge should restart the GC time limit count which is |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
471 // for full GC's. |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
472 size_policy->reset_gc_overhead_limit_count(); |
0 | 473 if (UseAdaptiveSizePolicy) { |
474 // Calculate the new survivor size and tenuring threshold | |
475 | |
476 if (PrintAdaptiveSizePolicy) { | |
477 gclog_or_tty->print("AdaptiveSizeStart: "); | |
478 gclog_or_tty->stamp(); | |
479 gclog_or_tty->print_cr(" collection: %d ", | |
480 heap->total_collections()); | |
481 | |
482 if (Verbose) { | |
483 gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d" | |
484 " perm_gen_capacity: %d ", | |
485 old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes(), | |
486 perm_gen->capacity_in_bytes()); | |
487 } | |
488 } | |
489 | |
490 | |
491 if (UsePerfData) { | |
492 PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters(); | |
493 counters->update_old_eden_size( | |
494 size_policy->calculated_eden_size_in_bytes()); | |
495 counters->update_old_promo_size( | |
496 size_policy->calculated_promo_size_in_bytes()); | |
497 counters->update_old_capacity(old_gen->capacity_in_bytes()); | |
498 counters->update_young_capacity(young_gen->capacity_in_bytes()); | |
499 counters->update_survived(survived); | |
500 counters->update_promoted(promoted); | |
501 counters->update_survivor_overflowed(_survivor_overflow); | |
502 } | |
503 | |
504 size_t survivor_limit = | |
505 size_policy->max_survivor_size(young_gen->max_size()); | |
506 _tenuring_threshold = | |
507 size_policy->compute_survivor_space_size_and_threshold( | |
508 _survivor_overflow, | |
509 _tenuring_threshold, | |
510 survivor_limit); | |
511 | |
512 if (PrintTenuringDistribution) { | |
513 gclog_or_tty->cr(); | |
514 gclog_or_tty->print_cr("Desired survivor size %ld bytes, new threshold %d (max %d)", | |
515 size_policy->calculated_survivor_size_in_bytes(), | |
516 _tenuring_threshold, MaxTenuringThreshold); | |
517 } | |
518 | |
519 if (UsePerfData) { | |
520 PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters(); | |
521 counters->update_tenuring_threshold(_tenuring_threshold); | |
522 counters->update_survivor_size_counters(); | |
523 } | |
524 | |
525 // Do call at minor collections? | |
526 // Don't check if the size_policy is ready at this | |
527 // level. Let the size_policy check that internally. | |
528 if (UseAdaptiveSizePolicy && | |
529 UseAdaptiveGenerationSizePolicyAtMinorCollection && | |
530 ((gc_cause != GCCause::_java_lang_system_gc) || | |
531 UseAdaptiveSizePolicyWithSystemGC)) { | |
532 | |
533 // Calculate optimial free space amounts | |
534 assert(young_gen->max_size() > | |
535 young_gen->from_space()->capacity_in_bytes() + | |
536 young_gen->to_space()->capacity_in_bytes(), | |
537 "Sizes of space in young gen are out-of-bounds"); | |
538 size_t max_eden_size = young_gen->max_size() - | |
539 young_gen->from_space()->capacity_in_bytes() - | |
540 young_gen->to_space()->capacity_in_bytes(); | |
541 size_policy->compute_generation_free_space(young_gen->used_in_bytes(), | |
542 young_gen->eden_space()->used_in_bytes(), | |
543 old_gen->used_in_bytes(), | |
544 perm_gen->used_in_bytes(), | |
545 young_gen->eden_space()->capacity_in_bytes(), | |
546 old_gen->max_gen_size(), | |
547 max_eden_size, | |
548 false /* full gc*/, | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
549 gc_cause, |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
989
diff
changeset
|
550 heap->collector_policy()); |
0 | 551 |
552 } | |
553 // Resize the young generation at every collection | |
554 // even if new sizes have not been calculated. This is | |
555 // to allow resizes that may have been inhibited by the | |
556 // relative location of the "to" and "from" spaces. | |
557 | |
558 // Resizing the old gen at minor collects can cause increases | |
559 // that don't feed back to the generation sizing policy until | |
560 // a major collection. Don't resize the old gen here. | |
561 | |
562 heap->resize_young_gen(size_policy->calculated_eden_size_in_bytes(), | |
563 size_policy->calculated_survivor_size_in_bytes()); | |
564 | |
565 if (PrintAdaptiveSizePolicy) { | |
566 gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ", | |
567 heap->total_collections()); | |
568 } | |
569 } | |
570 | |
571 // Update the structure of the eden. With NUMA-eden CPU hotplugging or offlining can | |
572 // cause the change of the heap layout. Make sure eden is reshaped if that's the case. | |
573 // Also update() will case adaptive NUMA chunk resizing. | |
574 assert(young_gen->eden_space()->is_empty(), "eden space should be empty now"); | |
575 young_gen->eden_space()->update(); | |
576 | |
577 heap->gc_policy_counters()->update_counters(); | |
578 | |
579 heap->resize_all_tlabs(); | |
580 | |
581 assert(young_gen->to_space()->is_empty(), "to space should be empty now"); | |
582 } | |
583 | |
584 COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); | |
585 | |
586 NOT_PRODUCT(reference_processor()->verify_no_references_recorded()); | |
587 | |
588 // Re-verify object start arrays | |
589 if (VerifyObjectStartArray && | |
590 VerifyAfterGC) { | |
591 old_gen->verify_object_start_array(); | |
592 perm_gen->verify_object_start_array(); | |
593 } | |
594 | |
595 // Verify all old -> young cards are now precise | |
596 if (VerifyRememberedSets) { | |
597 // Precise verification will give false positives. Until this is fixed, | |
598 // use imprecise verification. | |
599 // CardTableExtension::verify_all_young_refs_precise(); | |
600 CardTableExtension::verify_all_young_refs_imprecise(); | |
601 } | |
602 | |
603 if (TraceGen0Time) accumulated_time()->stop(); | |
604 | |
605 if (PrintGC) { | |
606 if (PrintGCDetails) { | |
607 // Don't print a GC timestamp here. This is after the GC so | |
608 // would be confusing. | |
609 young_gen->print_used_change(young_gen_used_before); | |
610 } | |
611 heap->print_heap_change(prev_used); | |
612 } | |
613 | |
614 // Track memory usage and detect low memory | |
615 MemoryService::track_memory_usage(); | |
616 heap->update_counters(); | |
617 } | |
618 | |
619 if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) { | |
620 HandleMark hm; // Discard invalid handles created during verification | |
621 gclog_or_tty->print(" VerifyAfterGC:"); | |
622 Universe::verify(false); | |
623 } | |
624 | |
625 if (PrintHeapAtGC) { | |
626 Universe::print_heap_after_gc(); | |
627 } | |
628 | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
629 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
630 young_gen->eden_space()->check_mangled_unused_area_complete(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
631 young_gen->from_space()->check_mangled_unused_area_complete(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
632 young_gen->to_space()->check_mangled_unused_area_complete(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
633 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
634 |
0 | 635 scavenge_exit.update(); |
636 | |
637 if (PrintGCTaskTimeStamps) { | |
638 tty->print_cr("VM-Thread " INT64_FORMAT " " INT64_FORMAT " " INT64_FORMAT, | |
639 scavenge_entry.ticks(), scavenge_midpoint.ticks(), | |
640 scavenge_exit.ticks()); | |
641 gc_task_manager()->print_task_time_stamps(); | |
642 } | |
643 | |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
457
diff
changeset
|
644 #ifdef TRACESPINNING |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
457
diff
changeset
|
645 ParallelTaskTerminator::print_termination_counts(); |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
457
diff
changeset
|
646 #endif |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
457
diff
changeset
|
647 |
0 | 648 return !promotion_failure_occurred; |
649 } | |
650 | |
651 // This method iterates over all objects in the young generation, | |
652 // unforwarding markOops. It then restores any preserved mark oops, | |
653 // and clears the _preserved_mark_stack. | |
654 void PSScavenge::clean_up_failed_promotion() { | |
655 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
656 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
657 assert(promotion_failed(), "Sanity"); | |
658 | |
659 PSYoungGen* young_gen = heap->young_gen(); | |
660 | |
661 { | |
662 ResourceMark rm; | |
663 | |
664 // Unforward all pointers in the young gen. | |
665 PSPromotionFailedClosure unforward_closure; | |
666 young_gen->object_iterate(&unforward_closure); | |
667 | |
668 if (PrintGC && Verbose) { | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
669 gclog_or_tty->print_cr("Restoring %d marks", _preserved_oop_stack.size()); |
0 | 670 } |
671 | |
672 // Restore any saved marks. | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
673 while (!_preserved_oop_stack.is_empty()) { |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
674 oop obj = _preserved_oop_stack.pop(); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
675 markOop mark = _preserved_mark_stack.pop(); |
0 | 676 obj->set_mark(mark); |
677 } | |
678 | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
679 // Clear the preserved mark and oop stack caches. |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
680 _preserved_mark_stack.clear(true); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
681 _preserved_oop_stack.clear(true); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
682 _promotion_failed = false; |
0 | 683 } |
684 | |
685 // Reset the PromotionFailureALot counters. | |
686 NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();) | |
687 } | |
688 | |
689 // This method is called whenever an attempt to promote an object | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
690 // fails. Some markOops will need preservation, some will not. Note |
0 | 691 // that the entire eden is traversed after a failed promotion, with |
692 // all forwarded headers replaced by the default markOop. This means | |
693 // it is not neccessary to preserve most markOops. | |
694 void PSScavenge::oop_promotion_failed(oop obj, markOop obj_mark) { | |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
695 _promotion_failed = true; |
0 | 696 if (obj_mark->must_be_preserved_for_promotion_failure(obj)) { |
2038
74ee0db180fa
6807801: CMS: could save/restore fewer header words during scavenge
ysr
parents:
1972
diff
changeset
|
697 // Should use per-worker private stakcs hetre rather than |
74ee0db180fa
6807801: CMS: could save/restore fewer header words during scavenge
ysr
parents:
1972
diff
changeset
|
698 // locking a common pair of stacks. |
0 | 699 ThreadCritical tc; |
1836
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
700 _preserved_oop_stack.push(obj); |
894b1d7c7e01
6423256: GC stacks should use a better data structure
jcoomes
parents:
1706
diff
changeset
|
701 _preserved_mark_stack.push(obj_mark); |
0 | 702 } |
703 } | |
704 | |
705 bool PSScavenge::should_attempt_scavenge() { | |
706 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
707 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
708 PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters(); | |
709 | |
710 if (UsePerfData) { | |
711 counters->update_scavenge_skipped(not_skipped); | |
712 } | |
713 | |
714 PSYoungGen* young_gen = heap->young_gen(); | |
715 PSOldGen* old_gen = heap->old_gen(); | |
716 | |
717 if (!ScavengeWithObjectsInToSpace) { | |
718 // Do not attempt to promote unless to_space is empty | |
719 if (!young_gen->to_space()->is_empty()) { | |
720 _consecutive_skipped_scavenges++; | |
721 if (UsePerfData) { | |
722 counters->update_scavenge_skipped(to_space_not_empty); | |
723 } | |
724 return false; | |
725 } | |
726 } | |
727 | |
728 // Test to see if the scavenge will likely fail. | |
729 PSAdaptiveSizePolicy* policy = heap->size_policy(); | |
730 | |
731 // A similar test is done in the policy's should_full_GC(). If this is | |
732 // changed, decide if that test should also be changed. | |
733 size_t avg_promoted = (size_t) policy->padded_average_promoted_in_bytes(); | |
734 size_t promotion_estimate = MIN2(avg_promoted, young_gen->used_in_bytes()); | |
735 bool result = promotion_estimate < old_gen->free_in_bytes(); | |
736 | |
737 if (PrintGCDetails && Verbose) { | |
738 gclog_or_tty->print(result ? " do scavenge: " : " skip scavenge: "); | |
739 gclog_or_tty->print_cr(" average_promoted " SIZE_FORMAT | |
740 " padded_average_promoted " SIZE_FORMAT | |
741 " free in old gen " SIZE_FORMAT, | |
742 (size_t) policy->average_promoted_in_bytes(), | |
743 (size_t) policy->padded_average_promoted_in_bytes(), | |
744 old_gen->free_in_bytes()); | |
745 if (young_gen->used_in_bytes() < | |
746 (size_t) policy->padded_average_promoted_in_bytes()) { | |
747 gclog_or_tty->print_cr(" padded_promoted_average is greater" | |
748 " than maximum promotion = " SIZE_FORMAT, young_gen->used_in_bytes()); | |
749 } | |
750 } | |
751 | |
752 if (result) { | |
753 _consecutive_skipped_scavenges = 0; | |
754 } else { | |
755 _consecutive_skipped_scavenges++; | |
756 if (UsePerfData) { | |
757 counters->update_scavenge_skipped(promoted_too_large); | |
758 } | |
759 } | |
760 return result; | |
761 } | |
762 | |
763 // Used to add tasks | |
764 GCTaskManager* const PSScavenge::gc_task_manager() { | |
765 assert(ParallelScavengeHeap::gc_task_manager() != NULL, | |
766 "shouldn't return NULL"); | |
767 return ParallelScavengeHeap::gc_task_manager(); | |
768 } | |
769 | |
770 void PSScavenge::initialize() { | |
771 // Arguments must have been parsed | |
772 | |
773 if (AlwaysTenure) { | |
774 _tenuring_threshold = 0; | |
775 } else if (NeverTenure) { | |
776 _tenuring_threshold = markOopDesc::max_age + 1; | |
777 } else { | |
778 // We want to smooth out our startup times for the AdaptiveSizePolicy | |
779 _tenuring_threshold = (UseAdaptiveSizePolicy) ? InitialTenuringThreshold : | |
780 MaxTenuringThreshold; | |
781 } | |
782 | |
783 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | |
784 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | |
785 | |
786 PSYoungGen* young_gen = heap->young_gen(); | |
787 PSOldGen* old_gen = heap->old_gen(); | |
788 PSPermGen* perm_gen = heap->perm_gen(); | |
789 | |
790 // Set boundary between young_gen and old_gen | |
791 assert(perm_gen->reserved().end() <= old_gen->object_space()->bottom(), | |
792 "perm above old"); | |
793 assert(old_gen->reserved().end() <= young_gen->eden_space()->bottom(), | |
794 "old above young"); | |
795 _young_generation_boundary = young_gen->eden_space()->bottom(); | |
796 | |
797 // Initialize ref handling object for scavenging. | |
798 MemRegion mr = young_gen->reserved(); | |
799 _ref_processor = ReferenceProcessor::create_ref_processor( | |
800 mr, // span | |
801 true, // atomic_discovery | |
802 true, // mt_discovery | |
803 NULL, // is_alive_non_header | |
804 ParallelGCThreads, | |
805 ParallelRefProcEnabled); | |
806 | |
807 // Cache the cardtable | |
808 BarrierSet* bs = Universe::heap()->barrier_set(); | |
809 assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); | |
810 _card_table = (CardTableExtension*)bs; | |
811 | |
812 _counters = new CollectorCounters("PSScavenge", 0); | |
813 } |