void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) { // Recursively traverse all live objects and mark them GCTraceTime tm("phase 1", PrintGCDetails && Verbose, true, _gc_timer); trace(" 1"); ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); // General strong roots. { ParallelScavengeHeap::ParStrongRootsScope psrs; Universe::oops_do(mark_and_push_closure()); JNIHandles::oops_do(mark_and_push_closure()); // Global (strong) JNI handles CodeBlobToOopClosure each_active_code_blob(mark_and_push_closure(), /*do_marking=*/ true); Threads::oops_do(mark_and_push_closure(), &each_active_code_blob); ObjectSynchronizer::oops_do(mark_and_push_closure()); FlatProfiler::oops_do(mark_and_push_closure()); Management::oops_do(mark_and_push_closure()); JvmtiExport::oops_do(mark_and_push_closure()); SystemDictionary::always_strong_oops_do(mark_and_push_closure()); // Do not treat nmethods as strong roots for mark/sweep, since we can unload them. //CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(mark_and_push_closure())); } // Flush marking stack. follow_stack(); // Process reference objects found during marking { ref_processor()->setup_policy(clear_all_softrefs); const ReferenceProcessorStats& stats = ref_processor()->process_discovered_references( is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL, _gc_timer); gc_tracer()->report_gc_reference_stats(stats); } // Follow system dictionary roots and unload classes bool purged_class = SystemDictionary::do_unloading(is_alive_closure()); // Follow code cache roots CodeCache::do_unloading(is_alive_closure(), mark_and_push_closure(), purged_class); follow_stack(); // Flush marking stack // Update subklass/sibling/implementor links of live klasses follow_weak_klass_links(); assert(_marking_stack.is_empty(), "just drained"); // Visit memoized mdo's and clear unmarked weak refs follow_mdo_weak_refs(); assert(_marking_stack.is_empty(), "just drained"); // Visit interned string tables and delete unmarked oops StringTable::unlink(is_alive_closure()); // Clean up unreferenced symbols in symbol table. SymbolTable::unlink(); assert(_marking_stack.is_empty(), "stack should be empty by now"); _gc_tracer->report_object_count_after_gc(is_alive_closure()); }
void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) { // Recursively traverse all live objects and mark them GCTraceTime tm("phase 1", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id()); trace(" 1"); ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); // Need to clear claim bits before the tracing starts. ClassLoaderDataGraph::clear_claimed_marks(); // General strong roots. { ParallelScavengeHeap::ParStrongRootsScope psrs; Universe::oops_do(mark_and_push_closure()); JNIHandles::oops_do(mark_and_push_closure()); // Global (strong) JNI handles CLDToOopClosure mark_and_push_from_cld(mark_and_push_closure()); MarkingCodeBlobClosure each_active_code_blob(mark_and_push_closure(), !CodeBlobToOopClosure::FixRelocations); Threads::oops_do(mark_and_push_closure(), &mark_and_push_from_cld, &each_active_code_blob); ObjectSynchronizer::oops_do(mark_and_push_closure()); FlatProfiler::oops_do(mark_and_push_closure()); Management::oops_do(mark_and_push_closure()); JvmtiExport::oops_do(mark_and_push_closure()); SystemDictionary::always_strong_oops_do(mark_and_push_closure()); ClassLoaderDataGraph::always_strong_cld_do(follow_cld_closure()); // Do not treat nmethods as strong roots for mark/sweep, since we can unload them. //CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(mark_and_push_closure())); } // Flush marking stack. follow_stack(); // Process reference objects found during marking { ref_processor()->setup_policy(clear_all_softrefs); const ReferenceProcessorStats& stats = ref_processor()->process_discovered_references( is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL, _gc_timer, _gc_tracer->gc_id()); gc_tracer()->report_gc_reference_stats(stats); } // This is the point where the entire marking should have completed. assert(_marking_stack.is_empty(), "Marking should have completed"); // Unload classes and purge the SystemDictionary. bool purged_class = SystemDictionary::do_unloading(is_alive_closure()); // Unload nmethods. CodeCache::do_unloading(is_alive_closure(), purged_class); // Prune dead klasses from subklass/sibling/implementor lists. Klass::clean_weak_klass_links(is_alive_closure()); // Delete entries for dead interned strings. StringTable::unlink(is_alive_closure()); // Clean up unreferenced symbols in symbol table. SymbolTable::unlink(); _gc_tracer->report_object_count_after_gc(is_alive_closure()); }
void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) { assert(Universe::heap()->is_gc_active(), "called outside gc"); NOT_PRODUCT(GCTraceTime tm("MarkFromRootsTask", PrintGCDetails && TraceParallelOldGCTasks, true, NULL)); ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(which); PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm); switch (_root_type) { case universe: Universe::oops_do(&mark_and_push_closure); break; case jni_handles: JNIHandles::oops_do(&mark_and_push_closure); break; case threads: { ResourceMark rm; CodeBlobToOopClosure each_active_code_blob(&mark_and_push_closure, /*do_marking=*/ true); Threads::oops_do(&mark_and_push_closure, &each_active_code_blob); } break; case object_synchronizer: ObjectSynchronizer::oops_do(&mark_and_push_closure); break; case flat_profiler: FlatProfiler::oops_do(&mark_and_push_closure); break; case management: Management::oops_do(&mark_and_push_closure); break; case jvmti: JvmtiExport::oops_do(&mark_and_push_closure); break; case system_dictionary: SystemDictionary::always_strong_oops_do(&mark_and_push_closure); break; case code_cache: // Do not treat nmethods as strong roots for mark/sweep, since we can unload them. //CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(&mark_and_push_closure)); break; default: fatal("Unknown root type"); } // Do the real work cm->follow_marking_stacks(); }