21 * questions. |
21 * questions. |
22 * |
22 * |
23 */ |
23 */ |
24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
|
26 #include "aot/aotLoader.hpp" |
|
27 #include "classfile/classLoaderDataGraph.hpp" |
26 #include "classfile/stringTable.hpp" |
28 #include "classfile/stringTable.hpp" |
27 #include "code/codeCache.hpp" |
29 #include "code/codeCache.hpp" |
28 #include "gc/parallel/gcTaskManager.hpp" |
|
29 #include "gc/parallel/parallelScavengeHeap.hpp" |
30 #include "gc/parallel/parallelScavengeHeap.hpp" |
30 #include "gc/parallel/psAdaptiveSizePolicy.hpp" |
31 #include "gc/parallel/psAdaptiveSizePolicy.hpp" |
31 #include "gc/parallel/psClosure.inline.hpp" |
32 #include "gc/parallel/psClosure.inline.hpp" |
|
33 #include "gc/parallel/psCompactionManager.hpp" |
32 #include "gc/parallel/psMarkSweepProxy.hpp" |
34 #include "gc/parallel/psMarkSweepProxy.hpp" |
33 #include "gc/parallel/psParallelCompact.inline.hpp" |
35 #include "gc/parallel/psParallelCompact.inline.hpp" |
34 #include "gc/parallel/psPromotionManager.inline.hpp" |
36 #include "gc/parallel/psPromotionManager.inline.hpp" |
|
37 #include "gc/parallel/psRootType.hpp" |
35 #include "gc/parallel/psScavenge.inline.hpp" |
38 #include "gc/parallel/psScavenge.inline.hpp" |
36 #include "gc/parallel/psTasks.hpp" |
|
37 #include "gc/shared/gcCause.hpp" |
39 #include "gc/shared/gcCause.hpp" |
38 #include "gc/shared/gcHeapSummary.hpp" |
40 #include "gc/shared/gcHeapSummary.hpp" |
39 #include "gc/shared/gcId.hpp" |
41 #include "gc/shared/gcId.hpp" |
40 #include "gc/shared/gcLocker.hpp" |
42 #include "gc/shared/gcLocker.hpp" |
41 #include "gc/shared/gcTimer.hpp" |
43 #include "gc/shared/gcTimer.hpp" |
43 #include "gc/shared/gcTraceTime.inline.hpp" |
45 #include "gc/shared/gcTraceTime.inline.hpp" |
44 #include "gc/shared/isGCActiveMark.hpp" |
46 #include "gc/shared/isGCActiveMark.hpp" |
45 #include "gc/shared/referencePolicy.hpp" |
47 #include "gc/shared/referencePolicy.hpp" |
46 #include "gc/shared/referenceProcessor.hpp" |
48 #include "gc/shared/referenceProcessor.hpp" |
47 #include "gc/shared/referenceProcessorPhaseTimes.hpp" |
49 #include "gc/shared/referenceProcessorPhaseTimes.hpp" |
|
50 #include "gc/shared/scavengableNMethods.hpp" |
48 #include "gc/shared/spaceDecorator.hpp" |
51 #include "gc/shared/spaceDecorator.hpp" |
49 #include "gc/shared/weakProcessor.hpp" |
52 #include "gc/shared/weakProcessor.hpp" |
|
53 #include "gc/shared/workerPolicy.hpp" |
|
54 #include "gc/shared/workgroup.hpp" |
50 #include "memory/resourceArea.hpp" |
55 #include "memory/resourceArea.hpp" |
51 #include "memory/universe.hpp" |
56 #include "memory/universe.hpp" |
52 #include "logging/log.hpp" |
57 #include "logging/log.hpp" |
53 #include "oops/access.inline.hpp" |
58 #include "oops/access.inline.hpp" |
54 #include "oops/compressedOops.inline.hpp" |
59 #include "oops/compressedOops.inline.hpp" |
56 #include "runtime/biasedLocking.hpp" |
61 #include "runtime/biasedLocking.hpp" |
57 #include "runtime/handles.inline.hpp" |
62 #include "runtime/handles.inline.hpp" |
58 #include "runtime/threadCritical.hpp" |
63 #include "runtime/threadCritical.hpp" |
59 #include "runtime/vmThread.hpp" |
64 #include "runtime/vmThread.hpp" |
60 #include "runtime/vmOperations.hpp" |
65 #include "runtime/vmOperations.hpp" |
|
66 #include "services/management.hpp" |
61 #include "services/memoryService.hpp" |
67 #include "services/memoryService.hpp" |
62 #include "utilities/stack.inline.hpp" |
68 #include "utilities/stack.inline.hpp" |
63 |
69 |
64 HeapWord* PSScavenge::_to_space_top_before_gc = NULL; |
70 HeapWord* PSScavenge::_to_space_top_before_gc = NULL; |
65 int PSScavenge::_consecutive_skipped_scavenges = 0; |
71 int PSScavenge::_consecutive_skipped_scavenges = 0; |
73 elapsedTimer PSScavenge::_accumulated_time; |
79 elapsedTimer PSScavenge::_accumulated_time; |
74 STWGCTimer PSScavenge::_gc_timer; |
80 STWGCTimer PSScavenge::_gc_timer; |
75 ParallelScavengeTracer PSScavenge::_gc_tracer; |
81 ParallelScavengeTracer PSScavenge::_gc_tracer; |
76 CollectorCounters* PSScavenge::_counters = NULL; |
82 CollectorCounters* PSScavenge::_counters = NULL; |
77 |
83 |
|
84 static void scavenge_roots_work(ParallelRootType::Value root_type, uint worker_id) { |
|
85 assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); |
|
86 |
|
87 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(worker_id); |
|
88 PSScavengeRootsClosure roots_closure(pm); |
|
89 PSPromoteRootsClosure roots_to_old_closure(pm); |
|
90 |
|
91 switch (root_type) { |
|
92 case ParallelRootType::universe: |
|
93 Universe::oops_do(&roots_closure); |
|
94 break; |
|
95 |
|
96 case ParallelRootType::jni_handles: |
|
97 JNIHandles::oops_do(&roots_closure); |
|
98 break; |
|
99 |
|
100 case ParallelRootType::object_synchronizer: |
|
101 ObjectSynchronizer::oops_do(&roots_closure); |
|
102 break; |
|
103 |
|
104 case ParallelRootType::system_dictionary: |
|
105 SystemDictionary::oops_do(&roots_closure); |
|
106 break; |
|
107 |
|
108 case ParallelRootType::class_loader_data: |
|
109 { |
|
110 PSScavengeCLDClosure cld_closure(pm); |
|
111 ClassLoaderDataGraph::cld_do(&cld_closure); |
|
112 } |
|
113 break; |
|
114 |
|
115 case ParallelRootType::management: |
|
116 Management::oops_do(&roots_closure); |
|
117 break; |
|
118 |
|
119 case ParallelRootType::jvmti: |
|
120 JvmtiExport::oops_do(&roots_closure); |
|
121 break; |
|
122 |
|
123 case ParallelRootType::code_cache: |
|
124 { |
|
125 MarkingCodeBlobClosure code_closure(&roots_to_old_closure, CodeBlobToOopClosure::FixRelocations); |
|
126 ScavengableNMethods::nmethods_do(&code_closure); |
|
127 AOTLoader::oops_do(&roots_closure); |
|
128 } |
|
129 break; |
|
130 |
|
131 case ParallelRootType::sentinel: |
|
132 DEBUG_ONLY(default:) // DEBUG_ONLY hack will create compile error on release builds (-Wswitch) and runtime check on debug builds |
|
133 fatal("Bad enumeration value: %u", root_type); |
|
134 break; |
|
135 } |
|
136 |
|
137 // Do the real work |
|
138 pm->drain_stacks(false); |
|
139 } |
|
140 |
|
141 static void steal_work(ParallelTaskTerminator& terminator, uint worker_id) { |
|
142 assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); |
|
143 |
|
144 PSPromotionManager* pm = |
|
145 PSPromotionManager::gc_thread_promotion_manager(worker_id); |
|
146 pm->drain_stacks(true); |
|
147 guarantee(pm->stacks_empty(), |
|
148 "stacks should be empty at this point"); |
|
149 |
|
150 while (true) { |
|
151 StarTask p; |
|
152 if (PSPromotionManager::steal_depth(worker_id, p)) { |
|
153 TASKQUEUE_STATS_ONLY(pm->record_steal(p)); |
|
154 pm->process_popped_location_depth(p); |
|
155 pm->drain_stacks_depth(true); |
|
156 } else { |
|
157 if (terminator.offer_termination()) { |
|
158 break; |
|
159 } |
|
160 } |
|
161 } |
|
162 guarantee(pm->stacks_empty(), "stacks should be empty at this point"); |
|
163 } |
|
164 |
78 // Define before use |
165 // Define before use |
79 class PSIsAliveClosure: public BoolObjectClosure { |
166 class PSIsAliveClosure: public BoolObjectClosure { |
80 public: |
167 public: |
81 bool do_object_b(oop p) { |
168 bool do_object_b(oop p) { |
82 return (!PSScavenge::is_obj_in_young(p)) || p->is_forwarded(); |
169 return (!PSScavenge::is_obj_in_young(p)) || p->is_forwarded(); |
123 guarantee(_promotion_manager->stacks_empty(), |
210 guarantee(_promotion_manager->stacks_empty(), |
124 "stacks should be empty at this point"); |
211 "stacks should be empty at this point"); |
125 } |
212 } |
126 }; |
213 }; |
127 |
214 |
128 class PSRefProcTaskProxy: public GCTask { |
215 class PSRefProcTaskExecutor: public AbstractRefProcTaskExecutor { |
|
216 virtual void execute(ProcessTask& process_task, uint ergo_workers); |
|
217 }; |
|
218 |
|
219 class PSRefProcTask : public AbstractGangTask { |
129 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask; |
220 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask; |
130 ProcessTask & _rp_task; |
221 TaskTerminator _terminator; |
131 uint _work_id; |
222 ProcessTask& _task; |
|
223 uint _active_workers; |
|
224 |
132 public: |
225 public: |
133 PSRefProcTaskProxy(ProcessTask & rp_task, uint work_id) |
226 PSRefProcTask(ProcessTask& task, uint active_workers) |
134 : _rp_task(rp_task), |
227 : AbstractGangTask("PSRefProcTask"), |
135 _work_id(work_id) |
228 _terminator(active_workers, PSPromotionManager::stack_array_depth()), |
136 { } |
229 _task(task), |
137 |
230 _active_workers(active_workers) { |
138 private: |
231 } |
139 virtual char* name() { return (char *)"Process referents by policy in parallel"; } |
232 |
140 virtual void do_it(GCTaskManager* manager, uint which); |
233 virtual void work(uint worker_id) { |
|
234 PSPromotionManager* promotion_manager = |
|
235 PSPromotionManager::gc_thread_promotion_manager(worker_id); |
|
236 assert(promotion_manager != NULL, "sanity check"); |
|
237 PSKeepAliveClosure keep_alive(promotion_manager); |
|
238 PSEvacuateFollowersClosure evac_followers(promotion_manager); |
|
239 PSIsAliveClosure is_alive; |
|
240 _task.work(worker_id, is_alive, keep_alive, evac_followers); |
|
241 |
|
242 if (_task.marks_oops_alive() && _active_workers > 1) { |
|
243 steal_work(*_terminator.terminator(), worker_id); |
|
244 } |
|
245 } |
141 }; |
246 }; |
142 |
247 |
143 void PSRefProcTaskProxy::do_it(GCTaskManager* manager, uint which) |
248 void PSRefProcTaskExecutor::execute(ProcessTask& process_task, uint ergo_workers) { |
144 { |
249 PSRefProcTask task(process_task, ergo_workers); |
145 PSPromotionManager* promotion_manager = |
250 ParallelScavengeHeap::heap()->workers().run_task(&task); |
146 PSPromotionManager::gc_thread_promotion_manager(which); |
|
147 assert(promotion_manager != NULL, "sanity check"); |
|
148 PSKeepAliveClosure keep_alive(promotion_manager); |
|
149 PSEvacuateFollowersClosure evac_followers(promotion_manager); |
|
150 PSIsAliveClosure is_alive; |
|
151 _rp_task.work(_work_id, is_alive, keep_alive, evac_followers); |
|
152 } |
|
153 |
|
154 class PSRefProcTaskExecutor: public AbstractRefProcTaskExecutor { |
|
155 virtual void execute(ProcessTask& task, uint ergo_workers); |
|
156 }; |
|
157 |
|
158 void PSRefProcTaskExecutor::execute(ProcessTask& task, uint ergo_workers) |
|
159 { |
|
160 GCTaskQueue* q = GCTaskQueue::create(); |
|
161 GCTaskManager* manager = ParallelScavengeHeap::gc_task_manager(); |
|
162 uint active_workers = manager->active_workers(); |
|
163 |
|
164 assert(active_workers == ergo_workers, |
|
165 "Ergonomically chosen workers (%u) must be equal to active workers (%u)", |
|
166 ergo_workers, active_workers); |
|
167 |
|
168 for(uint i=0; i < active_workers; i++) { |
|
169 q->enqueue(new PSRefProcTaskProxy(task, i)); |
|
170 } |
|
171 TaskTerminator terminator(active_workers, |
|
172 (TaskQueueSetSuper*) PSPromotionManager::stack_array_depth()); |
|
173 if (task.marks_oops_alive() && active_workers > 1) { |
|
174 for (uint j = 0; j < active_workers; j++) { |
|
175 q->enqueue(new StealTask(terminator.terminator())); |
|
176 } |
|
177 } |
|
178 manager->execute_and_wait(q); |
|
179 } |
251 } |
180 |
252 |
181 // This method contains all heap specific policy for invoking scavenge. |
253 // This method contains all heap specific policy for invoking scavenge. |
182 // PSScavenge::invoke_no_policy() will do nothing but attempt to |
254 // PSScavenge::invoke_no_policy() will do nothing but attempt to |
183 // scavenge. It will not clean up after failed promotions, bail out if |
255 // scavenge. It will not clean up after failed promotions, bail out if |
219 } |
291 } |
220 |
292 |
221 return full_gc_done; |
293 return full_gc_done; |
222 } |
294 } |
223 |
295 |
224 class PSAddThreadRootsTaskClosure : public ThreadClosure { |
296 class PSThreadRootsTaskClosure : public ThreadClosure { |
225 private: |
297 uint _worker_id; |
226 GCTaskQueue* _q; |
|
227 |
|
228 public: |
298 public: |
229 PSAddThreadRootsTaskClosure(GCTaskQueue* q) : _q(q) { } |
299 PSThreadRootsTaskClosure(uint worker_id) : _worker_id(worker_id) { } |
230 void do_thread(Thread* t) { |
300 virtual void do_thread(Thread* thread) { |
231 _q->enqueue(new ThreadRootsTask(t)); |
301 assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); |
|
302 |
|
303 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(_worker_id); |
|
304 PSScavengeRootsClosure roots_closure(pm); |
|
305 MarkingCodeBlobClosure roots_in_blobs(&roots_closure, CodeBlobToOopClosure::FixRelocations); |
|
306 |
|
307 thread->oops_do(&roots_closure, &roots_in_blobs); |
|
308 |
|
309 // Do the real work |
|
310 pm->drain_stacks(false); |
|
311 } |
|
312 }; |
|
313 |
|
314 class ScavengeRootsTask : public AbstractGangTask { |
|
315 StrongRootsScope _strong_roots_scope; // needed for Threads::possibly_parallel_threads_do |
|
316 SequentialSubTasksDone _subtasks; |
|
317 PSOldGen* _old_gen; |
|
318 HeapWord* _gen_top; |
|
319 uint _active_workers; |
|
320 bool _is_empty; |
|
321 TaskTerminator _terminator; |
|
322 |
|
323 public: |
|
324 ScavengeRootsTask(PSOldGen* old_gen, |
|
325 HeapWord* gen_top, |
|
326 uint active_workers, |
|
327 bool is_empty) : |
|
328 AbstractGangTask("ScavengeRootsTask"), |
|
329 _strong_roots_scope(active_workers), |
|
330 _subtasks(), |
|
331 _old_gen(old_gen), |
|
332 _gen_top(gen_top), |
|
333 _active_workers(active_workers), |
|
334 _is_empty(is_empty), |
|
335 _terminator(active_workers, PSPromotionManager::vm_thread_promotion_manager()->stack_array_depth()) { |
|
336 _subtasks.set_n_threads(active_workers); |
|
337 _subtasks.set_n_tasks(ParallelRootType::sentinel); |
|
338 } |
|
339 |
|
340 virtual void work(uint worker_id) { |
|
341 ResourceMark rm; |
|
342 |
|
343 if (!_is_empty) { |
|
344 // There are only old-to-young pointers if there are objects |
|
345 // in the old gen. |
|
346 |
|
347 assert(_old_gen != NULL, "Sanity"); |
|
348 // There are no old-to-young pointers if the old gen is empty. |
|
349 assert(!_old_gen->object_space()->is_empty(), "Should not be called is there is no work"); |
|
350 assert(_old_gen->object_space()->contains(_gen_top) || _gen_top == _old_gen->object_space()->top(), "Sanity"); |
|
351 assert(worker_id < ParallelGCThreads, "Sanity"); |
|
352 |
|
353 { |
|
354 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(worker_id); |
|
355 PSCardTable* card_table = ParallelScavengeHeap::heap()->card_table(); |
|
356 |
|
357 card_table->scavenge_contents_parallel(_old_gen->start_array(), |
|
358 _old_gen->object_space(), |
|
359 _gen_top, |
|
360 pm, |
|
361 worker_id, |
|
362 _active_workers); |
|
363 |
|
364 // Do the real work |
|
365 pm->drain_stacks(false); |
|
366 } |
|
367 } |
|
368 |
|
369 for (uint root_type = 0; _subtasks.try_claim_task(root_type); /* empty */ ) { |
|
370 scavenge_roots_work(static_cast<ParallelRootType::Value>(root_type), worker_id); |
|
371 } |
|
372 _subtasks.all_tasks_completed(); |
|
373 |
|
374 PSThreadRootsTaskClosure closure(worker_id); |
|
375 Threads::possibly_parallel_threads_do(true /*parallel */, &closure); |
|
376 |
|
377 |
|
378 // If active_workers can exceed 1, add a steal_work(). |
|
379 // PSPromotionManager::drain_stacks_depth() does not fully drain its |
|
380 // stacks and expects a steal_work() to complete the draining if |
|
381 // ParallelGCThreads is > 1. |
|
382 |
|
383 if (_active_workers > 1) { |
|
384 steal_work(*_terminator.terminator() , worker_id); |
|
385 } |
232 } |
386 } |
233 }; |
387 }; |
234 |
388 |
235 // This method contains no policy. You should probably |
389 // This method contains no policy. You should probably |
236 // be calling invoke() instead. |
390 // be calling invoke() instead. |
326 #endif |
480 #endif |
327 |
481 |
328 reference_processor()->enable_discovery(); |
482 reference_processor()->enable_discovery(); |
329 reference_processor()->setup_policy(false); |
483 reference_processor()->setup_policy(false); |
330 |
484 |
331 PreGCValues pre_gc_values(heap); |
485 const PreGenGCValues pre_gc_values = heap->get_pre_gc_values(); |
332 |
486 |
333 // Reset our survivor overflow. |
487 // Reset our survivor overflow. |
334 set_survivor_overflow(false); |
488 set_survivor_overflow(false); |
335 |
489 |
336 // We need to save the old top values before |
490 // We need to save the old top values before |
337 // creating the promotion_manager. We pass the top |
491 // creating the promotion_manager. We pass the top |
338 // values to the card_table, to prevent it from |
492 // values to the card_table, to prevent it from |
339 // straying into the promotion labs. |
493 // straying into the promotion labs. |
340 HeapWord* old_top = old_gen->object_space()->top(); |
494 HeapWord* old_top = old_gen->object_space()->top(); |
341 |
495 |
342 // Release all previously held resources |
496 const uint active_workers = |
343 gc_task_manager()->release_all_resources(); |
497 WorkerPolicy::calc_active_workers(ParallelScavengeHeap::heap()->workers().total_workers(), |
344 |
498 ParallelScavengeHeap::heap()->workers().active_workers(), |
345 // Set the number of GC threads to be used in this collection |
499 Threads::number_of_non_daemon_threads()); |
346 gc_task_manager()->set_active_gang(); |
500 ParallelScavengeHeap::heap()->workers().update_active_workers(active_workers); |
347 gc_task_manager()->task_idle_workers(); |
|
348 // Get the active number of workers here and use that value |
|
349 // throughout the methods. |
|
350 uint active_workers = gc_task_manager()->active_workers(); |
|
351 |
501 |
352 PSPromotionManager::pre_scavenge(); |
502 PSPromotionManager::pre_scavenge(); |
353 |
503 |
354 // We'll use the promotion manager again later. |
504 // We'll use the promotion manager again later. |
355 PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager(); |
505 PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager(); |
356 { |
506 { |
357 GCTraceTime(Debug, gc, phases) tm("Scavenge", &_gc_timer); |
507 GCTraceTime(Debug, gc, phases) tm("Scavenge", &_gc_timer); |
358 ParallelScavengeHeap::ParStrongRootsScope psrs; |
508 |
359 |
509 ScavengeRootsTask task(old_gen, old_top, active_workers, old_gen->object_space()->is_empty()); |
360 GCTaskQueue* q = GCTaskQueue::create(); |
510 ParallelScavengeHeap::heap()->workers().run_task(&task); |
361 |
|
362 if (!old_gen->object_space()->is_empty()) { |
|
363 // There are only old-to-young pointers if there are objects |
|
364 // in the old gen. |
|
365 uint stripe_total = active_workers; |
|
366 for(uint i=0; i < stripe_total; i++) { |
|
367 q->enqueue(new OldToYoungRootsTask(old_gen, old_top, i, stripe_total)); |
|
368 } |
|
369 } |
|
370 |
|
371 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::universe)); |
|
372 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jni_handles)); |
|
373 // We scan the thread roots in parallel |
|
374 PSAddThreadRootsTaskClosure cl(q); |
|
375 Threads::java_threads_and_vm_thread_do(&cl); |
|
376 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::object_synchronizer)); |
|
377 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::management)); |
|
378 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary)); |
|
379 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::class_loader_data)); |
|
380 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti)); |
|
381 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache)); |
|
382 JVMCI_ONLY(q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmci));) |
|
383 |
|
384 TaskTerminator terminator(active_workers, |
|
385 (TaskQueueSetSuper*) promotion_manager->stack_array_depth()); |
|
386 // If active_workers can exceed 1, add a StrealTask. |
|
387 // PSPromotionManager::drain_stacks_depth() does not fully drain its |
|
388 // stacks and expects a StealTask to complete the draining if |
|
389 // ParallelGCThreads is > 1. |
|
390 if (gc_task_manager()->workers() > 1) { |
|
391 for (uint j = 0; j < active_workers; j++) { |
|
392 q->enqueue(new StealTask(terminator.terminator())); |
|
393 } |
|
394 } |
|
395 |
|
396 gc_task_manager()->execute_and_wait(q); |
|
397 } |
511 } |
398 |
512 |
399 scavenge_midpoint.update(); |
513 scavenge_midpoint.update(); |
400 |
514 |
401 // Process reference objects discovered during scavenge |
515 // Process reference objects discovered during scavenge |
597 |
711 |
598 if (log_is_enabled(Debug, gc, heap, exit)) { |
712 if (log_is_enabled(Debug, gc, heap, exit)) { |
599 accumulated_time()->stop(); |
713 accumulated_time()->stop(); |
600 } |
714 } |
601 |
715 |
602 young_gen->print_used_change(pre_gc_values.young_gen_used()); |
716 heap->print_heap_change(pre_gc_values); |
603 old_gen->print_used_change(pre_gc_values.old_gen_used()); |
|
604 MetaspaceUtils::print_metaspace_change(pre_gc_values.metadata_used()); |
|
605 |
717 |
606 // Track memory usage and detect low memory |
718 // Track memory usage and detect low memory |
607 MemoryService::track_memory_usage(); |
719 MemoryService::track_memory_usage(); |
608 heap->update_counters(); |
720 heap->update_counters(); |
609 |
|
610 gc_task_manager()->release_idle_workers(); |
|
611 } |
721 } |
612 |
722 |
613 if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) { |
723 if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) { |
614 HandleMark hm; // Discard invalid handles created during verification |
724 HandleMark hm; // Discard invalid handles created during verification |
615 Universe::verify("After GC"); |
725 Universe::verify("After GC"); |
719 |
821 |
720 void PSScavenge::initialize() { |
822 void PSScavenge::initialize() { |
721 // Arguments must have been parsed |
823 // Arguments must have been parsed |
722 |
824 |
723 if (AlwaysTenure || NeverTenure) { |
825 if (AlwaysTenure || NeverTenure) { |
724 assert(MaxTenuringThreshold == 0 || MaxTenuringThreshold == markOopDesc::max_age + 1, |
826 assert(MaxTenuringThreshold == 0 || MaxTenuringThreshold == markWord::max_age + 1, |
725 "MaxTenuringThreshold should be 0 or markOopDesc::max_age + 1, but is %d", (int) MaxTenuringThreshold); |
827 "MaxTenuringThreshold should be 0 or markWord::max_age + 1, but is %d", (int) MaxTenuringThreshold); |
726 _tenuring_threshold = MaxTenuringThreshold; |
828 _tenuring_threshold = MaxTenuringThreshold; |
727 } else { |
829 } else { |
728 // We want to smooth out our startup times for the AdaptiveSizePolicy |
830 // We want to smooth out our startup times for the AdaptiveSizePolicy |
729 _tenuring_threshold = (UseAdaptiveSizePolicy) ? InitialTenuringThreshold : |
831 _tenuring_threshold = (UseAdaptiveSizePolicy) ? InitialTenuringThreshold : |
730 MaxTenuringThreshold; |
832 MaxTenuringThreshold; |