在第一篇中曾经提到过,System.gc 曾经调用代码
Universe::heap()->collect(GCCause::_java_lang_system_gc);
void ParallelScavengeHeap::collect(GCCause::Cause cause) { assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock"); unsigned int gc_count = 0; unsigned int full_gc_count = 0; { MutexLocker ml(Heap_lock); // This value is guarded by the Heap_lock gc_count = Universe::heap()->total_collections(); full_gc_count = Universe::heap()->total_full_collections(); } VM_ParallelGCSystemGC op(gc_count, full_gc_count, cause); VMThread::execute(&op); }
http://blog.csdn.net/raintungli/article/details/7045024 VMThread
http://blog.csdn.net/raintungli/article/details/6553337 VMThread 执行的operation
而对VM_ParallelGCSystemGC, 最后VMThread 调用了doit的方法
void VM_ParallelGCSystemGC::doit() { JvmtiGCFullMarker jgcm; notify_gc_begin(true); ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "must be a ParallelScavengeHeap"); GCCauseSetter gccs(heap, _gc_cause); if (_gc_cause == GCCause::_gc_locker DEBUG_ONLY(|| _gc_cause == GCCause::_scavenge_alot)) { // If (and only if) the scavenge fails, this will invoke a full gc. heap->invoke_scavenge(); } else { heap->invoke_full_gc(false); } notify_gc_end(); }
当前线程提交了一个GC的operation 给了VMThread线程, 由VMThread线程来执行回收,因为VMThread线程是执行在Queue里的任务,也就是system.gc 未必会及时触发因为queue里可能还是有其他的任务在执行,同样VMThread在执行GC的时候,queue里的其他任务也会因此而无法执行比如thread.stop