1.1 --- a/src/share/vm/gc_implementation/shared/vmGCOperations.cpp Tue Jul 01 09:03:55 2014 +0200 1.2 +++ b/src/share/vm/gc_implementation/shared/vmGCOperations.cpp Mon Jul 07 10:12:40 2014 +0200 1.3 @@ -209,6 +209,43 @@ 1.4 gch->do_full_collection(gch->must_clear_all_soft_refs(), _max_level); 1.5 } 1.6 1.7 +bool VM_CollectForMetadataAllocation::initiate_concurrent_GC() { 1.8 +#if INCLUDE_ALL_GCS 1.9 + if (UseConcMarkSweepGC || UseG1GC) { 1.10 + if (UseConcMarkSweepGC && CMSClassUnloadingEnabled) { 1.11 + MetaspaceGC::set_should_concurrent_collect(true); 1.12 + } else if (UseG1GC) { 1.13 + G1CollectedHeap* g1h = G1CollectedHeap::heap(); 1.14 + g1h->g1_policy()->set_initiate_conc_mark_if_possible(); 1.15 + 1.16 + GCCauseSetter x(g1h, _gc_cause); 1.17 + 1.18 + // At this point we are supposed to start a concurrent cycle. We 1.19 + // will do so if one is not already in progress. 1.20 + bool should_start = g1h->g1_policy()->force_initial_mark_if_outside_cycle(_gc_cause); 1.21 + 1.22 + if (should_start) { 1.23 + double pause_target = g1h->g1_policy()->max_pause_time_ms(); 1.24 + g1h->do_collection_pause_at_safepoint(pause_target); 1.25 + } 1.26 + } 1.27 + 1.28 + return true; 1.29 + } 1.30 +#endif 1.31 + return false; 1.32 +} 1.33 + 1.34 +static void log_metaspace_alloc_failure_for_concurrent_GC() { 1.35 + if (Verbose && PrintGCDetails) { 1.36 + if (UseConcMarkSweepGC) { 1.37 + gclog_or_tty->print_cr("\nCMS full GC for Metaspace"); 1.38 + } else if (UseG1GC) { 1.39 + gclog_or_tty->print_cr("\nG1 full GC for Metaspace"); 1.40 + } 1.41 + } 1.42 +} 1.43 + 1.44 void VM_CollectForMetadataAllocation::doit() { 1.45 SvcGCMarker sgcm(SvcGCMarker::FULL); 1.46 1.47 @@ -220,54 +257,57 @@ 1.48 // a GC that freed space for the allocation. 1.49 if (!MetadataAllocationFailALot) { 1.50 _result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype); 1.51 - } 1.52 - 1.53 - if (_result == NULL) { 1.54 - if (UseConcMarkSweepGC) { 1.55 - if (CMSClassUnloadingEnabled) { 1.56 - MetaspaceGC::set_should_concurrent_collect(true); 1.57 - } 1.58 - // For CMS expand since the collection is going to be concurrent. 1.59 - _result = 1.60 - _loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype); 1.61 - } 1.62 - if (_result == NULL) { 1.63 - // Don't clear the soft refs yet. 1.64 - if (Verbose && PrintGCDetails && UseConcMarkSweepGC) { 1.65 - gclog_or_tty->print_cr("\nCMS full GC for Metaspace"); 1.66 - } 1.67 - heap->collect_as_vm_thread(GCCause::_metadata_GC_threshold); 1.68 - // After a GC try to allocate without expanding. Could fail 1.69 - // and expansion will be tried below. 1.70 - _result = 1.71 - _loader_data->metaspace_non_null()->allocate(_size, _mdtype); 1.72 - } 1.73 - if (_result == NULL) { 1.74 - // If still failing, allow the Metaspace to expand. 1.75 - // See delta_capacity_until_GC() for explanation of the 1.76 - // amount of the expansion. 1.77 - // This should work unless there really is no more space 1.78 - // or a MaxMetaspaceSize has been specified on the command line. 1.79 - _result = 1.80 - _loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype); 1.81 - if (_result == NULL) { 1.82 - // If expansion failed, do a last-ditch collection and try allocating 1.83 - // again. A last-ditch collection will clear softrefs. This 1.84 - // behavior is similar to the last-ditch collection done for perm 1.85 - // gen when it was full and a collection for failed allocation 1.86 - // did not free perm gen space. 1.87 - heap->collect_as_vm_thread(GCCause::_last_ditch_collection); 1.88 - _result = 1.89 - _loader_data->metaspace_non_null()->allocate(_size, _mdtype); 1.90 - } 1.91 - } 1.92 - if (Verbose && PrintGCDetails && _result == NULL) { 1.93 - gclog_or_tty->print_cr("\nAfter Metaspace GC failed to allocate size " 1.94 - SIZE_FORMAT, _size); 1.95 + if (_result != NULL) { 1.96 + return; 1.97 } 1.98 } 1.99 1.100 - if (_result == NULL && GC_locker::is_active_and_needs_gc()) { 1.101 + if (initiate_concurrent_GC()) { 1.102 + // For CMS and G1 expand since the collection is going to be concurrent. 1.103 + _result = _loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype); 1.104 + if (_result != NULL) { 1.105 + return; 1.106 + } 1.107 + 1.108 + log_metaspace_alloc_failure_for_concurrent_GC(); 1.109 + } 1.110 + 1.111 + // Don't clear the soft refs yet. 1.112 + heap->collect_as_vm_thread(GCCause::_metadata_GC_threshold); 1.113 + // After a GC try to allocate without expanding. Could fail 1.114 + // and expansion will be tried below. 1.115 + _result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype); 1.116 + if (_result != NULL) { 1.117 + return; 1.118 + } 1.119 + 1.120 + // If still failing, allow the Metaspace to expand. 1.121 + // See delta_capacity_until_GC() for explanation of the 1.122 + // amount of the expansion. 1.123 + // This should work unless there really is no more space 1.124 + // or a MaxMetaspaceSize has been specified on the command line. 1.125 + _result = _loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype); 1.126 + if (_result != NULL) { 1.127 + return; 1.128 + } 1.129 + 1.130 + // If expansion failed, do a last-ditch collection and try allocating 1.131 + // again. A last-ditch collection will clear softrefs. This 1.132 + // behavior is similar to the last-ditch collection done for perm 1.133 + // gen when it was full and a collection for failed allocation 1.134 + // did not free perm gen space. 1.135 + heap->collect_as_vm_thread(GCCause::_last_ditch_collection); 1.136 + _result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype); 1.137 + if (_result != NULL) { 1.138 + return; 1.139 + } 1.140 + 1.141 + if (Verbose && PrintGCDetails) { 1.142 + gclog_or_tty->print_cr("\nAfter Metaspace GC failed to allocate size " 1.143 + SIZE_FORMAT, _size); 1.144 + } 1.145 + 1.146 + if (GC_locker::is_active_and_needs_gc()) { 1.147 set_gc_locked(); 1.148 } 1.149 }