// Failed allocation policy. Must be called from the VM thread, and // only at a safepoint! Note that this method has policy for allocation // flow, and NOT collection policy. So we do not check for gc collection // time over limit here, that is the responsibility of the heap specific // collection methods. This method decides where to attempt allocations, // and when to attempt collections, but no collection specific policy. HeapWord* ParallelScavengeHeap::failed_mem_allocate(size_t size, bool is_tlab) { assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); assert(!Universe::heap()->is_gc_active(), "not reentrant"); assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock"); size_t mark_sweep_invocation_count = total_invocations(); // We assume (and assert!) that an allocation at this point will fail // unless we collect. // First level allocation failure, scavenge and allocate in young gen. GCCauseSetter gccs(this, GCCause::_allocation_failure); PSScavenge::invoke(); HeapWord* result = young_gen()->allocate(size, is_tlab); // Second level allocation failure. // Mark sweep and allocate in young generation. if (result == NULL) { // There is some chance the scavenge method decided to invoke mark_sweep. // Don't mark sweep twice if so. if (mark_sweep_invocation_count == total_invocations()) { invoke_full_gc(false); result = young_gen()->allocate(size, is_tlab); } } // Third level allocation failure. // After mark sweep and young generation allocation failure, // allocate in old generation. if (result == NULL && !is_tlab) { result = old_gen()->allocate(size, is_tlab); } // Fourth level allocation failure. We're running out of memory. // More complete mark sweep and allocate in young generation. if (result == NULL) { invoke_full_gc(true); result = young_gen()->allocate(size, is_tlab); } // Fifth level allocation failure. // After more complete mark sweep, allocate in old generation. if (result == NULL && !is_tlab) { result = old_gen()->allocate(size, is_tlab); } return result; }
// Failed allocation policy. Must be called from the VM thread, and // only at a safepoint! Note that this method has policy for allocation // flow, and NOT collection policy. So we do not check for gc collection // time over limit here, that is the responsibility of the heap specific // collection methods. This method decides where to attempt allocations, // and when to attempt collections, but no collection specific policy. HeapWord* ParallelScavengeHeap::failed_mem_allocate(size_t size) { assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); assert(!Universe::heap()->is_gc_active(), "not reentrant"); assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock"); // We assume that allocation in eden will fail unless we collect. // First level allocation failure, scavenge and allocate in young gen. GCCauseSetter gccs(this, GCCause::_allocation_failure); const bool invoked_full_gc = PSScavenge::invoke(); HeapWord* result = young_gen()->allocate(size); // Second level allocation failure. // Mark sweep and allocate in young generation. if (result == NULL && !invoked_full_gc) { invoke_full_gc(false); result = young_gen()->allocate(size); } death_march_check(result, size); // Third level allocation failure. // After mark sweep and young generation allocation failure, // allocate in old generation. if (result == NULL) { result = old_gen()->allocate(size); } // Fourth level allocation failure. We're running out of memory. // More complete mark sweep and allocate in young generation. if (result == NULL) { invoke_full_gc(true); result = young_gen()->allocate(size); } // Fifth level allocation failure. // After more complete mark sweep, allocate in old generation. if (result == NULL) { result = old_gen()->allocate(size); } return result; }
// // This is the policy code for permanent allocations which have failed // and require a collection. Note that just as in failed_mem_allocate, // we do not set collection policy, only where & when to allocate and // collect. HeapWord* ParallelScavengeHeap::failed_permanent_mem_allocate(size_t size) { assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); assert(!Universe::heap()->is_gc_active(), "not reentrant"); assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock"); assert(size > perm_gen()->free_in_words(), "Allocation should fail"); // We assume (and assert!) that an allocation at this point will fail // unless we collect. // First level allocation failure. Mark-sweep and allocate in perm gen. GCCauseSetter gccs(this, GCCause::_allocation_failure); invoke_full_gc(false); HeapWord* result = perm_gen()->allocate_permanent(size); // Second level allocation failure. We're running out of memory. if (result == NULL) { invoke_full_gc(true); result = perm_gen()->allocate_permanent(size); } return result; }
// This interface assumes that it's being called by the // vm thread. It collects the heap assuming that the // heap lock is already held and that we are executing in // the context of the vm thread. void ParallelScavengeHeap::collect_as_vm_thread(GCCause::Cause cause) { assert(Thread::current()->is_VM_thread(), "Precondition#1"); assert(Heap_lock->is_locked(), "Precondition#2"); GCCauseSetter gcs(this, cause); switch (cause) { case GCCause::_heap_inspection: case GCCause::_heap_dump: { HandleMark hm; invoke_full_gc(false); break; } default: // XXX FIX ME ShouldNotReachHere(); } }