comparison src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp @ 1387:0bfd3fb24150

6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit. Summary: Ensure a full GC that clears SoftReferences before throwing an out-of-memory Reviewed-by: ysr, jcoomes
author jmasa
date Tue, 13 Apr 2010 13:52:10 -0700
parents 2a1472c30599
children c18cbe5936b8
comparison
equal deleted inserted replaced
1361:6b73e879f1c2 1387:0bfd3fb24150
1 /* 1 /*
2 * Copyright 2001-2009 Sun Microsystems, Inc. All Rights Reserved. 2 * Copyright 2001-2010 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
44 // reasons, scavenge before full gc, or any other specialized behavior, it 44 // reasons, scavenge before full gc, or any other specialized behavior, it
45 // needs to be added here. 45 // needs to be added here.
46 // 46 //
47 // Note that this method should only be called from the vm_thread while 47 // Note that this method should only be called from the vm_thread while
48 // at a safepoint! 48 // at a safepoint!
49 //
50 // Note that the all_soft_refs_clear flag in the collector policy
51 // may be true because this method can be called without intervening
52 // activity. For example when the heap space is tight and full measure
53 // are being taken to free space.
54
49 void PSMarkSweep::invoke(bool maximum_heap_compaction) { 55 void PSMarkSweep::invoke(bool maximum_heap_compaction) {
50 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); 56 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
51 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); 57 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
52 assert(!Universe::heap()->is_gc_active(), "not reentrant"); 58 assert(!Universe::heap()->is_gc_active(), "not reentrant");
53 59
54 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); 60 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
55 GCCause::Cause gc_cause = heap->gc_cause(); 61 GCCause::Cause gc_cause = heap->gc_cause();
56 PSAdaptiveSizePolicy* policy = heap->size_policy(); 62 PSAdaptiveSizePolicy* policy = heap->size_policy();
57 63 IsGCActiveMark mark;
58 // Before each allocation/collection attempt, find out from the 64
59 // policy object if GCs are, on the whole, taking too long. If so, 65 if (ScavengeBeforeFullGC) {
60 // bail out without attempting a collection. The exceptions are 66 PSScavenge::invoke_no_policy();
61 // for explicitly requested GC's. 67 }
62 if (!policy->gc_time_limit_exceeded() || 68
63 GCCause::is_user_requested_gc(gc_cause) || 69 const bool clear_all_soft_refs =
64 GCCause::is_serviceability_requested_gc(gc_cause)) { 70 heap->collector_policy()->should_clear_all_soft_refs();
65 IsGCActiveMark mark; 71
66 72 int count = (maximum_heap_compaction)?1:MarkSweepAlwaysCompactCount;
67 if (ScavengeBeforeFullGC) { 73 IntFlagSetting flag_setting(MarkSweepAlwaysCompactCount, count);
68 PSScavenge::invoke_no_policy(); 74 PSMarkSweep::invoke_no_policy(clear_all_soft_refs || maximum_heap_compaction);
69 }
70
71 int count = (maximum_heap_compaction)?1:MarkSweepAlwaysCompactCount;
72 IntFlagSetting flag_setting(MarkSweepAlwaysCompactCount, count);
73 PSMarkSweep::invoke_no_policy(maximum_heap_compaction);
74 }
75 } 75 }
76 76
77 // This method contains no policy. You should probably 77 // This method contains no policy. You should probably
78 // be calling invoke() instead. 78 // be calling invoke() instead.
79 void PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) { 79 void PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
86 86
87 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); 87 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
88 GCCause::Cause gc_cause = heap->gc_cause(); 88 GCCause::Cause gc_cause = heap->gc_cause();
89 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); 89 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
90 PSAdaptiveSizePolicy* size_policy = heap->size_policy(); 90 PSAdaptiveSizePolicy* size_policy = heap->size_policy();
91
92 // The scope of casr should end after code that can change
93 // CollectorPolicy::_should_clear_all_soft_refs.
94 ClearedAllSoftRefs casr(clear_all_softrefs, heap->collector_policy());
91 95
92 PSYoungGen* young_gen = heap->young_gen(); 96 PSYoungGen* young_gen = heap->young_gen();
93 PSOldGen* old_gen = heap->old_gen(); 97 PSOldGen* old_gen = heap->old_gen();
94 PSPermGen* perm_gen = heap->perm_gen(); 98 PSPermGen* perm_gen = heap->perm_gen();
95 99
273 perm_gen->used_in_bytes(), 277 perm_gen->used_in_bytes(),
274 young_gen->eden_space()->capacity_in_bytes(), 278 young_gen->eden_space()->capacity_in_bytes(),
275 old_gen->max_gen_size(), 279 old_gen->max_gen_size(),
276 max_eden_size, 280 max_eden_size,
277 true /* full gc*/, 281 true /* full gc*/,
278 gc_cause); 282 gc_cause,
283 heap->collector_policy());
279 284
280 heap->resize_old_gen(size_policy->calculated_old_free_size_in_bytes()); 285 heap->resize_old_gen(size_policy->calculated_old_free_size_in_bytes());
281 286
282 // Don't resize the young generation at an major collection. A 287 // Don't resize the young generation at an major collection. A
283 // desired young generation size may have been calculated but 288 // desired young generation size may have been calculated but
324 } 329 }
325 330
326 // Track memory usage and detect low memory 331 // Track memory usage and detect low memory
327 MemoryService::track_memory_usage(); 332 MemoryService::track_memory_usage();
328 heap->update_counters(); 333 heap->update_counters();
329
330 if (PrintGCDetails) {
331 if (size_policy->print_gc_time_limit_would_be_exceeded()) {
332 if (size_policy->gc_time_limit_exceeded()) {
333 gclog_or_tty->print_cr(" GC time is exceeding GCTimeLimit "
334 "of %d%%", GCTimeLimit);
335 } else {
336 gclog_or_tty->print_cr(" GC time would exceed GCTimeLimit "
337 "of %d%%", GCTimeLimit);
338 }
339 }
340 size_policy->set_print_gc_time_limit_would_be_exceeded(false);
341 }
342 } 334 }
343 335
344 if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) { 336 if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
345 HandleMark hm; // Discard invalid handles created during verification 337 HandleMark hm; // Discard invalid handles created during verification
346 gclog_or_tty->print(" VerifyAfterGC:"); 338 gclog_or_tty->print(" VerifyAfterGC:");