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& marked_for_unloading, bool clear_all_softrefs) { // Recursively traverse all live objects and mark them EventMark m("1 mark object"); TraceTime tm("phase 1", PrintGC && Verbose, true, gclog_or_tty); trace(" 1"); ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); // General strong roots. Universe::oops_do(mark_and_push_closure()); JNIHandles::oops_do(mark_and_push_closure()); // Global (strong) JNI handles Threads::oops_do(mark_and_push_closure()); ObjectSynchronizer::oops_do(mark_and_push_closure()); FlatProfiler::oops_do(mark_and_push_closure()); SystemDictionary::always_strong_oops_do(mark_and_push_closure()); guarantee(!jvmdi::enabled(), "Should not be used with jvmdi"); vmSymbols::oops_do(mark_and_push_closure()); // Flush marking stack. follow_stack(); // Process reference objects found during marking ReferencePolicy *soft_ref_policy; if (clear_all_softrefs) { soft_ref_policy = new AlwaysClearPolicy(); } else { NOT_COMPILER2(soft_ref_policy = new LRUCurrentHeapPolicy();) COMPILER2_ONLY(soft_ref_policy = new LRUMaxHeapPolicy();) }
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 MarkSweep::follow_weak_klass_links() { // All klasses on the revisit stack are marked at this point. // Update and follow all subklass, sibling and implementor links. for (int i = 0; i < _revisit_klass_stack->length(); i++) { _revisit_klass_stack->at(i)->follow_weak_klass_links(&is_alive,&keep_alive); } follow_stack(); }
void MarkSweep::follow_weak_klass_links() { // All klasses on the revisit stack are marked at this point. // Update and follow all subklass, sibling and implementor links. if (PrintRevisitStats) { gclog_or_tty->print_cr("#classes in system dictionary = %d", SystemDictionary::number_of_classes()); gclog_or_tty->print_cr("Revisit klass stack length = %d", _revisit_klass_stack->length()); } for (int i = 0; i < _revisit_klass_stack->length(); i++) { _revisit_klass_stack->at(i)->follow_weak_klass_links(&is_alive,&keep_alive); } follow_stack(); }
template <class T> inline void MarkSweep::follow_root(T* p) { assert(!Universe::heap()->is_in_reserved(p), "roots shouldn't be things within the heap"); T heap_oop = oopDesc::load_heap_oop(p); if (!oopDesc::is_null(heap_oop)) { oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); if (!obj->mark()->is_marked()) { mark_object(obj); follow_object(obj); } } follow_stack(); }
void MarkSweep::follow_mdo_weak_refs() { // All strongly reachable oops have been marked at this point; // we can visit and clear any weak references from MDO's which // we memoized during the strong marking phase. assert(_marking_stack->is_empty(), "Marking stack should be empty"); if (PrintRevisitStats) { gclog_or_tty->print_cr("#classes in system dictionary = %d", SystemDictionary::number_of_classes()); gclog_or_tty->print_cr("Revisit MDO stack length = %d", _revisit_mdo_stack->length()); } for (int i = 0; i < _revisit_mdo_stack->length(); i++) { _revisit_mdo_stack->at(i)->follow_weak_refs(&is_alive); } follow_stack(); }
void MarkSweep::follow_weak_klass_links() { // All klasses on the revisit stack are marked at this point. // Update and follow all subklass, sibling and implementor links. if (PrintRevisitStats) { gclog_or_tty->print_cr("#classes in system dictionary = %d", SystemDictionary::number_of_classes()); gclog_or_tty->print_cr("Revisit klass stack size = " SIZE_FORMAT, _revisit_klass_stack.size()); } while (!_revisit_klass_stack.is_empty()) { Klass* const k = _revisit_klass_stack.pop(); k->follow_weak_klass_links(&is_alive, &keep_alive); } follow_stack(); }
void MarkSweep::follow_root(oop* p) { assert(!Universe::heap()->is_in_reserved(p), "roots shouldn't be things within the heap"); #ifdef VALIDATE_MARK_SWEEP if (ValidateMarkSweep) { guarantee(!_root_refs_stack->contains(p), "should only be in here once"); _root_refs_stack->push(p); } #endif oop m = *p; if (m && !m->mark()->is_marked()) { mark_object(m); m->follow_contents(); // Follow contents of the marked object } follow_stack(); }
template <class T> inline void MarkSweep::follow_root(T* p) { assert(!Universe::heap()->is_in_reserved(p), "roots shouldn't be things within the heap"); #ifdef VALIDATE_MARK_SWEEP if (ValidateMarkSweep) { guarantee(!_root_refs_stack->contains(p), "should only be in here once"); _root_refs_stack->push(p); } #endif T heap_oop = oopDesc::load_heap_oop(p); if (!oopDesc::is_null(heap_oop)) { oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); if (!obj->mark()->is_marked()) { mark_object(obj); obj->follow_contents(); } } follow_stack(); }
void MarkSweep::FollowStackClosure::do_void() { follow_stack(); }