45 #include "gc/shared/genArguments.hpp" |
45 #include "gc/shared/genArguments.hpp" |
46 #include "gc/shared/gcVMOperations.hpp" |
46 #include "gc/shared/gcVMOperations.hpp" |
47 #include "gc/shared/genCollectedHeap.hpp" |
47 #include "gc/shared/genCollectedHeap.hpp" |
48 #include "gc/shared/genOopClosures.inline.hpp" |
48 #include "gc/shared/genOopClosures.inline.hpp" |
49 #include "gc/shared/generationSpec.hpp" |
49 #include "gc/shared/generationSpec.hpp" |
|
50 #include "gc/shared/locationPrinter.inline.hpp" |
50 #include "gc/shared/oopStorageParState.inline.hpp" |
51 #include "gc/shared/oopStorageParState.inline.hpp" |
51 #include "gc/shared/scavengableNMethods.hpp" |
52 #include "gc/shared/scavengableNMethods.hpp" |
52 #include "gc/shared/space.hpp" |
53 #include "gc/shared/space.hpp" |
53 #include "gc/shared/strongRootsScope.hpp" |
54 #include "gc/shared/strongRootsScope.hpp" |
54 #include "gc/shared/weakProcessor.hpp" |
55 #include "gc/shared/weakProcessor.hpp" |
102 // HeapWordSize). |
103 // HeapWordSize). |
103 guarantee(HeapWordSize == wordSize, "HeapWordSize must equal wordSize"); |
104 guarantee(HeapWordSize == wordSize, "HeapWordSize must equal wordSize"); |
104 |
105 |
105 // Allocate space for the heap. |
106 // Allocate space for the heap. |
106 |
107 |
107 char* heap_address; |
108 ReservedHeapSpace heap_rs = allocate(HeapAlignment); |
108 ReservedSpace heap_rs; |
|
109 |
|
110 heap_address = allocate(HeapAlignment, &heap_rs); |
|
111 |
109 |
112 if (!heap_rs.is_reserved()) { |
110 if (!heap_rs.is_reserved()) { |
113 vm_shutdown_during_initialization( |
111 vm_shutdown_during_initialization( |
114 "Could not reserve enough space for object heap"); |
112 "Could not reserve enough space for object heap"); |
115 return JNI_ENOMEM; |
113 return JNI_ENOMEM; |
116 } |
114 } |
117 |
115 |
118 initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size())); |
116 initialize_reserved_region(heap_rs); |
119 |
117 |
120 _rem_set = create_rem_set(reserved_region()); |
118 _rem_set = create_rem_set(heap_rs.region()); |
121 _rem_set->initialize(); |
119 _rem_set->initialize(); |
122 CardTableBarrierSet *bs = new CardTableBarrierSet(_rem_set); |
120 CardTableBarrierSet *bs = new CardTableBarrierSet(_rem_set); |
123 bs->initialize(); |
121 bs->initialize(); |
124 BarrierSet::set_barrier_set(bs); |
122 BarrierSet::set_barrier_set(bs); |
125 |
123 |
126 ReservedSpace young_rs = heap_rs.first_part(_young_gen_spec->max_size(), false, false); |
124 ReservedSpace young_rs = heap_rs.first_part(_young_gen_spec->max_size(), false, false); |
127 _young_gen = _young_gen_spec->init(young_rs, rem_set()); |
125 _young_gen = _young_gen_spec->init(young_rs, rem_set()); |
128 heap_rs = heap_rs.last_part(_young_gen_spec->max_size()); |
126 ReservedSpace old_rs = heap_rs.last_part(_young_gen_spec->max_size()); |
129 |
127 |
130 ReservedSpace old_rs = heap_rs.first_part(_old_gen_spec->max_size(), false, false); |
128 old_rs = old_rs.first_part(_old_gen_spec->max_size(), false, false); |
131 _old_gen = _old_gen_spec->init(old_rs, rem_set()); |
129 _old_gen = _old_gen_spec->init(old_rs, rem_set()); |
132 clear_incremental_collection_failed(); |
130 clear_incremental_collection_failed(); |
133 |
131 |
134 return JNI_OK; |
132 return JNI_OK; |
135 } |
133 } |
163 } |
160 } |
164 assert(total_reserved % alignment == 0, |
161 assert(total_reserved % alignment == 0, |
165 "Gen size; total_reserved=" SIZE_FORMAT ", alignment=" |
162 "Gen size; total_reserved=" SIZE_FORMAT ", alignment=" |
166 SIZE_FORMAT, total_reserved, alignment); |
163 SIZE_FORMAT, total_reserved, alignment); |
167 |
164 |
168 *heap_rs = Universe::reserve_heap(total_reserved, alignment); |
165 ReservedHeapSpace heap_rs = Universe::reserve_heap(total_reserved, alignment); |
169 |
166 |
170 os::trace_page_sizes("Heap", |
167 os::trace_page_sizes("Heap", |
171 MinHeapSize, |
168 MinHeapSize, |
172 total_reserved, |
169 total_reserved, |
173 alignment, |
170 alignment, |
174 heap_rs->base(), |
171 heap_rs.base(), |
175 heap_rs->size()); |
172 heap_rs.size()); |
176 |
173 |
177 return heap_rs->base(); |
174 return heap_rs; |
178 } |
175 } |
179 |
176 |
180 class GenIsScavengable : public BoolObjectClosure { |
177 class GenIsScavengable : public BoolObjectClosure { |
181 public: |
178 public: |
182 bool do_object_b(oop obj) { |
179 bool do_object_b(oop obj) { |
202 } |
199 } |
203 |
200 |
204 void GenCollectedHeap::ref_processing_init() { |
201 void GenCollectedHeap::ref_processing_init() { |
205 _young_gen->ref_processor_init(); |
202 _young_gen->ref_processor_init(); |
206 _old_gen->ref_processor_init(); |
203 _old_gen->ref_processor_init(); |
|
204 } |
|
205 |
|
206 PreGenGCValues GenCollectedHeap::get_pre_gc_values() const { |
|
207 const DefNewGeneration* const def_new_gen = (DefNewGeneration*) young_gen(); |
|
208 |
|
209 return PreGenGCValues(def_new_gen->used(), |
|
210 def_new_gen->capacity(), |
|
211 def_new_gen->eden()->used(), |
|
212 def_new_gen->eden()->capacity(), |
|
213 def_new_gen->from()->used(), |
|
214 def_new_gen->from()->capacity(), |
|
215 old_gen()->used(), |
|
216 old_gen()->capacity()); |
207 } |
217 } |
208 |
218 |
209 GenerationSpec* GenCollectedHeap::young_gen_spec() const { |
219 GenerationSpec* GenCollectedHeap::young_gen_spec() const { |
210 return _young_gen_spec; |
220 return _young_gen_spec; |
211 } |
221 } |
573 const bool do_clear_all_soft_refs = clear_all_soft_refs || |
583 const bool do_clear_all_soft_refs = clear_all_soft_refs || |
574 soft_ref_policy()->should_clear_all_soft_refs(); |
584 soft_ref_policy()->should_clear_all_soft_refs(); |
575 |
585 |
576 ClearedAllSoftRefs casr(do_clear_all_soft_refs, soft_ref_policy()); |
586 ClearedAllSoftRefs casr(do_clear_all_soft_refs, soft_ref_policy()); |
577 |
587 |
578 const size_t metadata_prev_used = MetaspaceUtils::used_bytes(); |
|
579 |
|
580 |
|
581 FlagSetting fl(_is_gc_active, true); |
588 FlagSetting fl(_is_gc_active, true); |
582 |
589 |
583 bool complete = full && (max_generation == OldGen); |
590 bool complete = full && (max_generation == OldGen); |
584 bool old_collects_young = complete && !ScavengeBeforeFullGC; |
591 bool old_collects_young = complete && !ScavengeBeforeFullGC; |
585 bool do_young_collection = !old_collects_young && _young_gen->should_collect(full, size, is_tlab); |
592 bool do_young_collection = !old_collects_young && _young_gen->should_collect(full, size, is_tlab); |
586 |
593 |
587 size_t young_prev_used = _young_gen->used(); |
594 const PreGenGCValues pre_gc_values = get_pre_gc_values(); |
588 size_t old_prev_used = _old_gen->used(); |
|
589 |
595 |
590 bool run_verification = total_collections() >= VerifyGCStartAt; |
596 bool run_verification = total_collections() >= VerifyGCStartAt; |
591 bool prepared_for_verification = false; |
597 bool prepared_for_verification = false; |
592 bool do_full_collection = false; |
598 bool do_full_collection = false; |
593 |
599 |
625 do_full_collection = should_do_full_collection(size, full, is_tlab, max_generation); |
631 do_full_collection = should_do_full_collection(size, full, is_tlab, max_generation); |
626 if (!do_full_collection) { |
632 if (!do_full_collection) { |
627 // Adjust generation sizes. |
633 // Adjust generation sizes. |
628 _young_gen->compute_new_size(); |
634 _young_gen->compute_new_size(); |
629 |
635 |
630 print_heap_change(young_prev_used, old_prev_used); |
636 print_heap_change(pre_gc_values); |
631 MetaspaceUtils::print_metaspace_change(metadata_prev_used); |
|
632 |
637 |
633 // Track memory usage and detect low memory after GC finishes |
638 // Track memory usage and detect low memory after GC finishes |
634 MemoryService::track_memory_usage(); |
639 MemoryService::track_memory_usage(); |
635 |
640 |
636 gc_epilogue(complete); |
641 gc_epilogue(complete); |
684 MetaspaceUtils::verify_metrics(); |
689 MetaspaceUtils::verify_metrics(); |
685 // Resize the metaspace capacity after full collections |
690 // Resize the metaspace capacity after full collections |
686 MetaspaceGC::compute_new_size(); |
691 MetaspaceGC::compute_new_size(); |
687 update_full_collections_completed(); |
692 update_full_collections_completed(); |
688 |
693 |
689 print_heap_change(young_prev_used, old_prev_used); |
694 print_heap_change(pre_gc_values); |
690 MetaspaceUtils::print_metaspace_change(metadata_prev_used); |
|
691 |
695 |
692 // Track memory usage and detect low memory after GC finishes |
696 // Track memory usage and detect low memory after GC finishes |
693 MemoryService::track_memory_usage(); |
697 MemoryService::track_memory_usage(); |
694 |
698 |
695 // Need to tell the epilogue code we are done with Full GC, regardless what was |
699 // Need to tell the epilogue code we are done with Full GC, regardless what was |
861 #if INCLUDE_AOT |
865 #if INCLUDE_AOT |
862 if (UseAOT && _process_strong_tasks->try_claim_task(GCH_PS_aot_oops_do)) { |
866 if (UseAOT && _process_strong_tasks->try_claim_task(GCH_PS_aot_oops_do)) { |
863 AOTLoader::oops_do(strong_roots); |
867 AOTLoader::oops_do(strong_roots); |
864 } |
868 } |
865 #endif |
869 #endif |
866 #if INCLUDE_JVMCI |
|
867 if (EnableJVMCI && _process_strong_tasks->try_claim_task(GCH_PS_jvmci_oops_do)) { |
|
868 JVMCI::oops_do(strong_roots); |
|
869 } |
|
870 #endif |
|
871 if (_process_strong_tasks->try_claim_task(GCH_PS_SystemDictionary_oops_do)) { |
870 if (_process_strong_tasks->try_claim_task(GCH_PS_SystemDictionary_oops_do)) { |
872 SystemDictionary::oops_do(strong_roots); |
871 SystemDictionary::oops_do(strong_roots); |
873 } |
872 } |
874 |
873 |
875 if (_process_strong_tasks->try_claim_task(GCH_PS_CodeCache_oops_do)) { |
874 if (_process_strong_tasks->try_claim_task(GCH_PS_CodeCache_oops_do)) { |
952 } |
951 } |
953 |
952 |
954 // public collection interfaces |
953 // public collection interfaces |
955 |
954 |
956 void GenCollectedHeap::collect(GCCause::Cause cause) { |
955 void GenCollectedHeap::collect(GCCause::Cause cause) { |
957 if (cause == GCCause::_wb_young_gc) { |
956 if ((cause == GCCause::_wb_young_gc) || |
958 // Young collection for the WhiteBox API. |
957 (cause == GCCause::_gc_locker)) { |
|
958 // Young collection for WhiteBox or GCLocker. |
959 collect(cause, YoungGen); |
959 collect(cause, YoungGen); |
960 } else { |
960 } else { |
961 #ifdef ASSERT |
961 #ifdef ASSERT |
962 if (cause == GCCause::_scavenge_alot) { |
962 if (cause == GCCause::_scavenge_alot) { |
963 // Young collection only. |
963 // Young collection only. |
991 |
991 |
992 void GenCollectedHeap::collect_locked(GCCause::Cause cause, GenerationType max_generation) { |
992 void GenCollectedHeap::collect_locked(GCCause::Cause cause, GenerationType max_generation) { |
993 // Read the GC count while holding the Heap_lock |
993 // Read the GC count while holding the Heap_lock |
994 unsigned int gc_count_before = total_collections(); |
994 unsigned int gc_count_before = total_collections(); |
995 unsigned int full_gc_count_before = total_full_collections(); |
995 unsigned int full_gc_count_before = total_full_collections(); |
|
996 |
|
997 if (GCLocker::should_discard(cause, gc_count_before)) { |
|
998 return; |
|
999 } |
|
1000 |
996 { |
1001 { |
997 MutexUnlocker mu(Heap_lock); // give up heap lock, execute gets it back |
1002 MutexUnlocker mu(Heap_lock); // give up heap lock, execute gets it back |
998 VM_GenCollectFull op(gc_count_before, full_gc_count_before, |
1003 VM_GenCollectFull op(gc_count_before, full_gc_count_before, |
999 cause, max_generation); |
1004 cause, max_generation); |
1000 VMThread::execute(&op); |
1005 VMThread::execute(&op); |
1005 do_full_collection(clear_all_soft_refs, OldGen); |
1010 do_full_collection(clear_all_soft_refs, OldGen); |
1006 } |
1011 } |
1007 |
1012 |
1008 void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs, |
1013 void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs, |
1009 GenerationType last_generation) { |
1014 GenerationType last_generation) { |
1010 GenerationType local_last_generation; |
|
1011 if (!incremental_collection_will_fail(false /* don't consult_young */) && |
|
1012 gc_cause() == GCCause::_gc_locker) { |
|
1013 local_last_generation = YoungGen; |
|
1014 } else { |
|
1015 local_last_generation = last_generation; |
|
1016 } |
|
1017 |
|
1018 do_collection(true, // full |
1015 do_collection(true, // full |
1019 clear_all_soft_refs, // clear_all_soft_refs |
1016 clear_all_soft_refs, // clear_all_soft_refs |
1020 0, // size |
1017 0, // size |
1021 false, // is_tlab |
1018 false, // is_tlab |
1022 local_last_generation); // last_generation |
1019 last_generation); // last_generation |
1023 // Hack XXX FIX ME !!! |
1020 // Hack XXX FIX ME !!! |
1024 // A scavenge may not have been attempted, or may have |
1021 // A scavenge may not have been attempted, or may have |
1025 // been attempted and failed, because the old gen was too full |
1022 // been attempted and failed, because the old gen was too full |
1026 if (local_last_generation == YoungGen && gc_cause() == GCCause::_gc_locker && |
1023 if (gc_cause() == GCCause::_gc_locker && incremental_collection_failed()) { |
1027 incremental_collection_will_fail(false /* don't consult_young */)) { |
|
1028 log_debug(gc, jni)("GC locker: Trying a full collection because scavenge failed"); |
1024 log_debug(gc, jni)("GC locker: Trying a full collection because scavenge failed"); |
1029 // This time allow the old gen to be collected as well |
1025 // This time allow the old gen to be collected as well |
1030 do_collection(true, // full |
1026 do_collection(true, // full |
1031 clear_all_soft_refs, // clear_all_soft_refs |
1027 clear_all_soft_refs, // clear_all_soft_refs |
1032 0, // size |
1028 0, // size |
1268 } |
1264 } |
1269 |
1265 |
1270 void GenCollectedHeap::print_gc_threads_on(outputStream* st) const { |
1266 void GenCollectedHeap::print_gc_threads_on(outputStream* st) const { |
1271 } |
1267 } |
1272 |
1268 |
|
1269 bool GenCollectedHeap::print_location(outputStream* st, void* addr) const { |
|
1270 return BlockLocationPrinter<GenCollectedHeap>::print_location(st, addr); |
|
1271 } |
|
1272 |
1273 void GenCollectedHeap::print_tracing_info() const { |
1273 void GenCollectedHeap::print_tracing_info() const { |
1274 if (log_is_enabled(Debug, gc, heap, exit)) { |
1274 if (log_is_enabled(Debug, gc, heap, exit)) { |
1275 LogStreamHandle(Debug, gc, heap, exit) lsh; |
1275 LogStreamHandle(Debug, gc, heap, exit) lsh; |
1276 _young_gen->print_summary_info_on(&lsh); |
1276 _young_gen->print_summary_info_on(&lsh); |
1277 _old_gen->print_summary_info_on(&lsh); |
1277 _old_gen->print_summary_info_on(&lsh); |
1278 } |
1278 } |
1279 } |
1279 } |
1280 |
1280 |
1281 void GenCollectedHeap::print_heap_change(size_t young_prev_used, size_t old_prev_used) const { |
1281 void GenCollectedHeap::print_heap_change(const PreGenGCValues& pre_gc_values) const { |
1282 log_info(gc, heap)("%s: " SIZE_FORMAT "K->" SIZE_FORMAT "K(" SIZE_FORMAT "K)", |
1282 const DefNewGeneration* const def_new_gen = (DefNewGeneration*) young_gen(); |
1283 _young_gen->short_name(), young_prev_used / K, _young_gen->used() /K, _young_gen->capacity() /K); |
1283 |
1284 log_info(gc, heap)("%s: " SIZE_FORMAT "K->" SIZE_FORMAT "K(" SIZE_FORMAT "K)", |
1284 log_info(gc, heap)(HEAP_CHANGE_FORMAT" " |
1285 _old_gen->short_name(), old_prev_used / K, _old_gen->used() /K, _old_gen->capacity() /K); |
1285 HEAP_CHANGE_FORMAT" " |
|
1286 HEAP_CHANGE_FORMAT, |
|
1287 HEAP_CHANGE_FORMAT_ARGS(def_new_gen->short_name(), |
|
1288 pre_gc_values.young_gen_used(), |
|
1289 pre_gc_values.young_gen_capacity(), |
|
1290 def_new_gen->used(), |
|
1291 def_new_gen->capacity()), |
|
1292 HEAP_CHANGE_FORMAT_ARGS("Eden", |
|
1293 pre_gc_values.eden_used(), |
|
1294 pre_gc_values.eden_capacity(), |
|
1295 def_new_gen->eden()->used(), |
|
1296 def_new_gen->eden()->capacity()), |
|
1297 HEAP_CHANGE_FORMAT_ARGS("From", |
|
1298 pre_gc_values.from_used(), |
|
1299 pre_gc_values.from_capacity(), |
|
1300 def_new_gen->from()->used(), |
|
1301 def_new_gen->from()->capacity())); |
|
1302 log_info(gc, heap)(HEAP_CHANGE_FORMAT, |
|
1303 HEAP_CHANGE_FORMAT_ARGS(old_gen()->short_name(), |
|
1304 pre_gc_values.old_gen_used(), |
|
1305 pre_gc_values.old_gen_capacity(), |
|
1306 old_gen()->used(), |
|
1307 old_gen()->capacity())); |
|
1308 MetaspaceUtils::print_metaspace_change(pre_gc_values.metaspace_sizes()); |
1286 } |
1309 } |
1287 |
1310 |
1288 class GenGCPrologueClosure: public GenCollectedHeap::GenClosure { |
1311 class GenGCPrologueClosure: public GenCollectedHeap::GenClosure { |
1289 private: |
1312 private: |
1290 bool _full; |
1313 bool _full; |