comparison src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp @ 4095:bca17e38de00

6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads Summary: Select number of GC threads dynamically based on heap usage and number of Java threads Reviewed-by: johnc, ysr, jcoomes
author jmasa
date Tue, 09 Aug 2011 10:16:01 -0700
parents 4dfb2df418f2
children aa3d708d67c4
comparison
equal deleted inserted replaced
4094:3a298e04d914 4095:bca17e38de00
179 }; 179 };
180 180
181 void PSRefProcTaskExecutor::execute(ProcessTask& task) 181 void PSRefProcTaskExecutor::execute(ProcessTask& task)
182 { 182 {
183 GCTaskQueue* q = GCTaskQueue::create(); 183 GCTaskQueue* q = GCTaskQueue::create();
184 for(uint i=0; i<ParallelGCThreads; i++) { 184 GCTaskManager* manager = ParallelScavengeHeap::gc_task_manager();
185 for(uint i=0; i < manager->active_workers(); i++) {
185 q->enqueue(new PSRefProcTaskProxy(task, i)); 186 q->enqueue(new PSRefProcTaskProxy(task, i));
186 } 187 }
187 ParallelTaskTerminator terminator( 188 ParallelTaskTerminator terminator(manager->active_workers(),
188 ParallelScavengeHeap::gc_task_manager()->workers(),
189 (TaskQueueSetSuper*) PSPromotionManager::stack_array_depth()); 189 (TaskQueueSetSuper*) PSPromotionManager::stack_array_depth());
190 if (task.marks_oops_alive() && ParallelGCThreads > 1) { 190 if (task.marks_oops_alive() && manager->active_workers() > 1) {
191 for (uint j=0; j<ParallelGCThreads; j++) { 191 for (uint j = 0; j < manager->active_workers(); j++) {
192 q->enqueue(new StealTask(&terminator)); 192 q->enqueue(new StealTask(&terminator));
193 } 193 }
194 } 194 }
195 ParallelScavengeHeap::gc_task_manager()->execute_and_wait(q); 195 manager->execute_and_wait(q);
196 } 196 }
197 197
198 198
199 void PSRefProcTaskExecutor::execute(EnqueueTask& task) 199 void PSRefProcTaskExecutor::execute(EnqueueTask& task)
200 { 200 {
201 GCTaskQueue* q = GCTaskQueue::create(); 201 GCTaskQueue* q = GCTaskQueue::create();
202 for(uint i=0; i<ParallelGCThreads; i++) { 202 GCTaskManager* manager = ParallelScavengeHeap::gc_task_manager();
203 for(uint i=0; i < manager->active_workers(); i++) {
203 q->enqueue(new PSRefEnqueueTaskProxy(task, i)); 204 q->enqueue(new PSRefEnqueueTaskProxy(task, i));
204 } 205 }
205 ParallelScavengeHeap::gc_task_manager()->execute_and_wait(q); 206 manager->execute_and_wait(q);
206 } 207 }
207 208
208 // This method contains all heap specific policy for invoking scavenge. 209 // This method contains all heap specific policy for invoking scavenge.
209 // PSScavenge::invoke_no_policy() will do nothing but attempt to 210 // PSScavenge::invoke_no_policy() will do nothing but attempt to
210 // scavenge. It will not clean up after failed promotions, bail out if 211 // scavenge. It will not clean up after failed promotions, bail out if
373 HeapWord* perm_top = perm_gen->object_space()->top(); 374 HeapWord* perm_top = perm_gen->object_space()->top();
374 375
375 // Release all previously held resources 376 // Release all previously held resources
376 gc_task_manager()->release_all_resources(); 377 gc_task_manager()->release_all_resources();
377 378
379 // Set the number of GC threads to be used in this collection
380 gc_task_manager()->set_active_gang();
381 gc_task_manager()->task_idle_workers();
382 // Get the active number of workers here and use that value
383 // throughout the methods.
384 uint active_workers = gc_task_manager()->active_workers();
385 heap->set_par_threads(active_workers);
386
378 PSPromotionManager::pre_scavenge(); 387 PSPromotionManager::pre_scavenge();
379 388
380 // We'll use the promotion manager again later. 389 // We'll use the promotion manager again later.
381 PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager(); 390 PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager();
382 { 391 {
383 // TraceTime("Roots"); 392 // TraceTime("Roots");
384 ParallelScavengeHeap::ParStrongRootsScope psrs; 393 ParallelScavengeHeap::ParStrongRootsScope psrs;
385 394
386 GCTaskQueue* q = GCTaskQueue::create(); 395 GCTaskQueue* q = GCTaskQueue::create();
387 396
388 for(uint i=0; i<ParallelGCThreads; i++) { 397 uint stripe_total = active_workers;
389 q->enqueue(new OldToYoungRootsTask(old_gen, old_top, i)); 398 for(uint i=0; i < stripe_total; i++) {
399 q->enqueue(new OldToYoungRootsTask(old_gen, old_top, i, stripe_total));
390 } 400 }
391 401
392 q->enqueue(new SerialOldToYoungRootsTask(perm_gen, perm_top)); 402 q->enqueue(new SerialOldToYoungRootsTask(perm_gen, perm_top));
393 403
394 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::universe)); 404 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::universe));
401 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary)); 411 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary));
402 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti)); 412 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti));
403 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache)); 413 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache));
404 414
405 ParallelTaskTerminator terminator( 415 ParallelTaskTerminator terminator(
406 gc_task_manager()->workers(), 416 active_workers,
407 (TaskQueueSetSuper*) promotion_manager->stack_array_depth()); 417 (TaskQueueSetSuper*) promotion_manager->stack_array_depth());
408 if (ParallelGCThreads>1) { 418 if (active_workers > 1) {
409 for (uint j=0; j<ParallelGCThreads; j++) { 419 for (uint j = 0; j < active_workers; j++) {
410 q->enqueue(new StealTask(&terminator)); 420 q->enqueue(new StealTask(&terminator));
411 } 421 }
412 } 422 }
413 423
414 gc_task_manager()->execute_and_wait(q); 424 gc_task_manager()->execute_and_wait(q);
417 scavenge_midpoint.update(); 427 scavenge_midpoint.update();
418 428
419 // Process reference objects discovered during scavenge 429 // Process reference objects discovered during scavenge
420 { 430 {
421 reference_processor()->setup_policy(false); // not always_clear 431 reference_processor()->setup_policy(false); // not always_clear
432 reference_processor()->set_active_mt_degree(active_workers);
422 PSKeepAliveClosure keep_alive(promotion_manager); 433 PSKeepAliveClosure keep_alive(promotion_manager);
423 PSEvacuateFollowersClosure evac_followers(promotion_manager); 434 PSEvacuateFollowersClosure evac_followers(promotion_manager);
424 if (reference_processor()->processing_is_mt()) { 435 if (reference_processor()->processing_is_mt()) {
425 PSRefProcTaskExecutor task_executor; 436 PSRefProcTaskExecutor task_executor;
426 reference_processor()->process_discovered_references( 437 reference_processor()->process_discovered_references(
620 } 631 }
621 632
622 // Track memory usage and detect low memory 633 // Track memory usage and detect low memory
623 MemoryService::track_memory_usage(); 634 MemoryService::track_memory_usage();
624 heap->update_counters(); 635 heap->update_counters();
636
637 gc_task_manager()->release_idle_workers();
625 } 638 }
626 639
627 if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) { 640 if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
628 HandleMark hm; // Discard invalid handles created during verification 641 HandleMark hm; // Discard invalid handles created during verification
629 gclog_or_tty->print(" VerifyAfterGC:"); 642 gclog_or_tty->print(" VerifyAfterGC:");
802 "old above young"); 815 "old above young");
803 _young_generation_boundary = young_gen->eden_space()->bottom(); 816 _young_generation_boundary = young_gen->eden_space()->bottom();
804 817
805 // Initialize ref handling object for scavenging. 818 // Initialize ref handling object for scavenging.
806 MemRegion mr = young_gen->reserved(); 819 MemRegion mr = young_gen->reserved();
820
807 _ref_processor = 821 _ref_processor =
808 new ReferenceProcessor(mr, // span 822 new ReferenceProcessor(mr, // span
809 ParallelRefProcEnabled && (ParallelGCThreads > 1), // mt processing 823 ParallelRefProcEnabled && (ParallelGCThreads > 1), // mt processing
810 (int) ParallelGCThreads, // mt processing degree 824 (int) ParallelGCThreads, // mt processing degree
811 true, // mt discovery 825 true, // mt discovery