36 #include "gc/g1/g1CollectorPolicy.hpp" |
36 #include "gc/g1/g1CollectorPolicy.hpp" |
37 #include "gc/g1/g1CollectorState.hpp" |
37 #include "gc/g1/g1CollectorState.hpp" |
38 #include "gc/g1/g1ConcurrentRefine.hpp" |
38 #include "gc/g1/g1ConcurrentRefine.hpp" |
39 #include "gc/g1/g1ConcurrentRefineThread.hpp" |
39 #include "gc/g1/g1ConcurrentRefineThread.hpp" |
40 #include "gc/g1/g1EvacStats.inline.hpp" |
40 #include "gc/g1/g1EvacStats.inline.hpp" |
|
41 #include "gc/g1/g1FullCollector.hpp" |
41 #include "gc/g1/g1FullGCScope.hpp" |
42 #include "gc/g1/g1FullGCScope.hpp" |
42 #include "gc/g1/g1GCPhaseTimes.hpp" |
43 #include "gc/g1/g1GCPhaseTimes.hpp" |
43 #include "gc/g1/g1HeapSizingPolicy.hpp" |
44 #include "gc/g1/g1HeapSizingPolicy.hpp" |
44 #include "gc/g1/g1HeapTransition.hpp" |
45 #include "gc/g1/g1HeapTransition.hpp" |
45 #include "gc/g1/g1HeapVerifier.hpp" |
46 #include "gc/g1/g1HeapVerifier.hpp" |
46 #include "gc/g1/g1HotCardCache.hpp" |
47 #include "gc/g1/g1HotCardCache.hpp" |
47 #include "gc/g1/g1OopClosures.inline.hpp" |
48 #include "gc/g1/g1OopClosures.inline.hpp" |
48 #include "gc/g1/g1ParScanThreadState.inline.hpp" |
49 #include "gc/g1/g1ParScanThreadState.inline.hpp" |
49 #include "gc/g1/g1Policy.hpp" |
50 #include "gc/g1/g1Policy.hpp" |
50 #include "gc/g1/g1RegionToSpaceMapper.hpp" |
51 #include "gc/g1/g1RegionToSpaceMapper.hpp" |
51 #include "gc/g1/g1RemSet.inline.hpp" |
52 #include "gc/g1/g1RemSet.hpp" |
52 #include "gc/g1/g1RootClosures.hpp" |
53 #include "gc/g1/g1RootClosures.hpp" |
53 #include "gc/g1/g1RootProcessor.hpp" |
54 #include "gc/g1/g1RootProcessor.hpp" |
54 #include "gc/g1/g1SerialFullCollector.hpp" |
|
55 #include "gc/g1/g1StringDedup.hpp" |
55 #include "gc/g1/g1StringDedup.hpp" |
56 #include "gc/g1/g1YCTypes.hpp" |
56 #include "gc/g1/g1YCTypes.hpp" |
57 #include "gc/g1/g1YoungRemSetSamplingThread.hpp" |
57 #include "gc/g1/g1YoungRemSetSamplingThread.hpp" |
58 #include "gc/g1/heapRegion.inline.hpp" |
58 #include "gc/g1/heapRegion.inline.hpp" |
59 #include "gc/g1/heapRegionRemSet.hpp" |
59 #include "gc/g1/heapRegionRemSet.hpp" |
141 // The from card cache is not the memory that is actually committed. So we cannot |
141 // The from card cache is not the memory that is actually committed. So we cannot |
142 // take advantage of the zero_filled parameter. |
142 // take advantage of the zero_filled parameter. |
143 reset_from_card_cache(start_idx, num_regions); |
143 reset_from_card_cache(start_idx, num_regions); |
144 } |
144 } |
145 |
145 |
|
146 |
|
147 HeapRegion* G1CollectedHeap::new_heap_region(uint hrs_index, |
|
148 MemRegion mr) { |
|
149 return new HeapRegion(hrs_index, bot(), mr); |
|
150 } |
|
151 |
146 // Private methods. |
152 // Private methods. |
147 |
153 |
148 HeapRegion* |
154 HeapRegion* |
149 G1CollectedHeap::new_region_try_secondary_free_list(bool is_old) { |
155 G1CollectedHeap::new_region_try_secondary_free_list(bool is_old) { |
150 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); |
156 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); |
1153 MetaspaceGC::compute_new_size(); |
1159 MetaspaceGC::compute_new_size(); |
1154 } |
1160 } |
1155 |
1161 |
1156 void G1CollectedHeap::abort_refinement() { |
1162 void G1CollectedHeap::abort_refinement() { |
1157 if (_hot_card_cache->use_cache()) { |
1163 if (_hot_card_cache->use_cache()) { |
1158 _hot_card_cache->reset_card_counts(); |
|
1159 _hot_card_cache->reset_hot_cache(); |
1164 _hot_card_cache->reset_hot_cache(); |
1160 } |
1165 } |
1161 |
1166 |
1162 // Discard all remembered set updates. |
1167 // Discard all remembered set updates. |
1163 JavaThread::dirty_card_queue_set().abandon_logs(); |
1168 JavaThread::dirty_card_queue_set().abandon_logs(); |
1197 ref_processor_stw()->verify_no_references_recorded(); |
1202 ref_processor_stw()->verify_no_references_recorded(); |
1198 ref_processor_cm()->verify_no_references_recorded(); |
1203 ref_processor_cm()->verify_no_references_recorded(); |
1199 } |
1204 } |
1200 |
1205 |
1201 void G1CollectedHeap::print_heap_after_full_collection(G1HeapTransition* heap_transition) { |
1206 void G1CollectedHeap::print_heap_after_full_collection(G1HeapTransition* heap_transition) { |
|
1207 // Post collection logging. |
|
1208 // We should do this after we potentially resize the heap so |
|
1209 // that all the COMMIT / UNCOMMIT events are generated before |
|
1210 // the compaction events. |
1202 print_hrm_post_compaction(); |
1211 print_hrm_post_compaction(); |
1203 heap_transition->print(); |
1212 heap_transition->print(); |
1204 print_heap_after_gc(); |
1213 print_heap_after_gc(); |
1205 print_heap_regions(); |
1214 print_heap_regions(); |
1206 #ifdef TRACESPINNING |
1215 #ifdef TRACESPINNING |
1219 verify_before_full_collection(scope->is_explicit_gc()); |
1228 verify_before_full_collection(scope->is_explicit_gc()); |
1220 |
1229 |
1221 gc_prologue(true); |
1230 gc_prologue(true); |
1222 prepare_heap_for_full_collection(); |
1231 prepare_heap_for_full_collection(); |
1223 |
1232 |
1224 G1SerialFullCollector serial(scope, ref_processor_stw()); |
1233 G1FullCollector collector(scope, ref_processor_stw(), concurrent_mark()->next_mark_bitmap(), workers()->active_workers()); |
1225 serial.prepare_collection(); |
1234 collector.prepare_collection(); |
1226 serial.collect(); |
1235 collector.collect(); |
1227 serial.complete_collection(); |
1236 collector.complete_collection(); |
1228 |
1237 |
1229 prepare_heap_for_mutators(); |
1238 prepare_heap_for_mutators(); |
1230 |
1239 |
1231 g1_policy()->record_full_collection_end(); |
1240 g1_policy()->record_full_collection_end(); |
1232 gc_epilogue(true); |
1241 gc_epilogue(true); |
1233 |
1242 |
1234 // Post collection verification. |
|
1235 verify_after_full_collection(); |
1243 verify_after_full_collection(); |
1236 |
1244 |
1237 // Post collection logging. |
|
1238 // We should do this after we potentially resize the heap so |
|
1239 // that all the COMMIT / UNCOMMIT events are generated before |
|
1240 // the compaction events. |
|
1241 print_heap_after_full_collection(scope->heap_transition()); |
1245 print_heap_after_full_collection(scope->heap_transition()); |
1242 } |
1246 } |
1243 |
1247 |
1244 bool G1CollectedHeap::do_full_collection(bool explicit_gc, |
1248 bool G1CollectedHeap::do_full_collection(bool explicit_gc, |
1245 bool clear_all_soft_refs) { |
1249 bool clear_all_soft_refs) { |
1267 bool dummy = do_full_collection(true, /* explicit_gc */ |
1271 bool dummy = do_full_collection(true, /* explicit_gc */ |
1268 clear_all_soft_refs); |
1272 clear_all_soft_refs); |
1269 } |
1273 } |
1270 |
1274 |
1271 void G1CollectedHeap::resize_if_necessary_after_full_collection() { |
1275 void G1CollectedHeap::resize_if_necessary_after_full_collection() { |
1272 // Include bytes that will be pre-allocated to support collections, as "used". |
1276 // Capacity, free and used after the GC counted as full regions to |
1273 const size_t used_after_gc = used(); |
1277 // include the waste in the following calculations. |
1274 const size_t capacity_after_gc = capacity(); |
1278 const size_t capacity_after_gc = capacity(); |
1275 const size_t free_after_gc = capacity_after_gc - used_after_gc; |
1279 const size_t used_after_gc = capacity_after_gc - unused_committed_regions_in_bytes(); |
1276 |
1280 |
1277 // This is enforced in arguments.cpp. |
1281 // This is enforced in arguments.cpp. |
1278 assert(MinHeapFreeRatio <= MaxHeapFreeRatio, |
1282 assert(MinHeapFreeRatio <= MaxHeapFreeRatio, |
1279 "otherwise the code below doesn't make sense"); |
1283 "otherwise the code below doesn't make sense"); |
1280 |
1284 |
1324 if (capacity_after_gc < minimum_desired_capacity) { |
1328 if (capacity_after_gc < minimum_desired_capacity) { |
1325 // Don't expand unless it's significant |
1329 // Don't expand unless it's significant |
1326 size_t expand_bytes = minimum_desired_capacity - capacity_after_gc; |
1330 size_t expand_bytes = minimum_desired_capacity - capacity_after_gc; |
1327 |
1331 |
1328 log_debug(gc, ergo, heap)("Attempt heap expansion (capacity lower than min desired capacity after Full GC). " |
1332 log_debug(gc, ergo, heap)("Attempt heap expansion (capacity lower than min desired capacity after Full GC). " |
1329 "Capacity: " SIZE_FORMAT "B occupancy: " SIZE_FORMAT "B min_desired_capacity: " SIZE_FORMAT "B (" UINTX_FORMAT " %%)", |
1333 "Capacity: " SIZE_FORMAT "B occupancy: " SIZE_FORMAT "B live: " SIZE_FORMAT "B " |
1330 capacity_after_gc, used_after_gc, minimum_desired_capacity, MinHeapFreeRatio); |
1334 "min_desired_capacity: " SIZE_FORMAT "B (" UINTX_FORMAT " %%)", |
|
1335 capacity_after_gc, used_after_gc, used(), minimum_desired_capacity, MinHeapFreeRatio); |
1331 |
1336 |
1332 expand(expand_bytes, _workers); |
1337 expand(expand_bytes, _workers); |
1333 |
1338 |
1334 // No expansion, now see if we want to shrink |
1339 // No expansion, now see if we want to shrink |
1335 } else if (capacity_after_gc > maximum_desired_capacity) { |
1340 } else if (capacity_after_gc > maximum_desired_capacity) { |
1336 // Capacity too large, compute shrinking size |
1341 // Capacity too large, compute shrinking size |
1337 size_t shrink_bytes = capacity_after_gc - maximum_desired_capacity; |
1342 size_t shrink_bytes = capacity_after_gc - maximum_desired_capacity; |
1338 |
1343 |
1339 log_debug(gc, ergo, heap)("Attempt heap shrinking (capacity higher than max desired capacity after Full GC). " |
1344 log_debug(gc, ergo, heap)("Attempt heap shrinking (capacity higher than max desired capacity after Full GC). " |
1340 "Capacity: " SIZE_FORMAT "B occupancy: " SIZE_FORMAT "B min_desired_capacity: " SIZE_FORMAT "B (" UINTX_FORMAT " %%)", |
1345 "Capacity: " SIZE_FORMAT "B occupancy: " SIZE_FORMAT "B live: " SIZE_FORMAT "B " |
1341 capacity_after_gc, used_after_gc, minimum_desired_capacity, MinHeapFreeRatio); |
1346 "maximum_desired_capacity: " SIZE_FORMAT "B (" UINTX_FORMAT " %%)", |
|
1347 capacity_after_gc, used_after_gc, used(), maximum_desired_capacity, MaxHeapFreeRatio); |
1342 |
1348 |
1343 shrink(shrink_bytes); |
1349 shrink(shrink_bytes); |
1344 } |
1350 } |
1345 } |
1351 } |
1346 |
1352 |
2260 |
2270 |
2261 void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const { |
2271 void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const { |
2262 _hrm.iterate(cl); |
2272 _hrm.iterate(cl); |
2263 } |
2273 } |
2264 |
2274 |
2265 void G1CollectedHeap::heap_region_par_iterate(HeapRegionClosure* cl, |
2275 void G1CollectedHeap::heap_region_par_iterate_from_worker_offset(HeapRegionClosure* cl, |
2266 uint worker_id, |
2276 HeapRegionClaimer *hrclaimer, |
2267 HeapRegionClaimer *hrclaimer) const { |
2277 uint worker_id) const { |
2268 _hrm.par_iterate(cl, worker_id, hrclaimer); |
2278 _hrm.par_iterate(cl, hrclaimer, hrclaimer->offset_for_worker(worker_id)); |
|
2279 } |
|
2280 |
|
2281 void G1CollectedHeap::heap_region_par_iterate_from_start(HeapRegionClosure* cl, |
|
2282 HeapRegionClaimer *hrclaimer) const { |
|
2283 _hrm.par_iterate(cl, hrclaimer, 0); |
2269 } |
2284 } |
2270 |
2285 |
2271 void G1CollectedHeap::collection_set_iterate(HeapRegionClosure* cl) { |
2286 void G1CollectedHeap::collection_set_iterate(HeapRegionClosure* cl) { |
2272 _collection_set.iterate(cl); |
2287 _collection_set.iterate(cl); |
2273 } |
2288 } |
2274 |
2289 |
2275 void G1CollectedHeap::collection_set_iterate_from(HeapRegionClosure *cl, uint worker_id) { |
2290 void G1CollectedHeap::collection_set_iterate_from(HeapRegionClosure *cl, uint worker_id) { |
2276 _collection_set.iterate_from(cl, worker_id, workers()->active_workers()); |
2291 _collection_set.iterate_from(cl, worker_id, workers()->active_workers()); |
2277 } |
|
2278 |
|
2279 HeapRegion* G1CollectedHeap::next_compaction_region(const HeapRegion* from) const { |
|
2280 HeapRegion* result = _hrm.next_region_in_heap(from); |
|
2281 while (result != NULL && result->is_pinned()) { |
|
2282 result = _hrm.next_region_in_heap(result); |
|
2283 } |
|
2284 return result; |
|
2285 } |
2292 } |
2286 |
2293 |
2287 HeapWord* G1CollectedHeap::block_start(const void* addr) const { |
2294 HeapWord* G1CollectedHeap::block_start(const void* addr) const { |
2288 HeapRegion* hr = heap_region_containing(addr); |
2295 HeapRegion* hr = heap_region_containing(addr); |
2289 return hr->block_start(addr); |
2296 return hr->block_start(addr); |
2373 const HeapRegion* hr, |
2380 const HeapRegion* hr, |
2374 const VerifyOption vo) const { |
2381 const VerifyOption vo) const { |
2375 switch (vo) { |
2382 switch (vo) { |
2376 case VerifyOption_G1UsePrevMarking: return is_obj_dead(obj, hr); |
2383 case VerifyOption_G1UsePrevMarking: return is_obj_dead(obj, hr); |
2377 case VerifyOption_G1UseNextMarking: return is_obj_ill(obj, hr); |
2384 case VerifyOption_G1UseNextMarking: return is_obj_ill(obj, hr); |
2378 case VerifyOption_G1UseMarkWord: return !obj->is_gc_marked() && !hr->is_archive(); |
2385 case VerifyOption_G1UseFullMarking: return is_obj_dead_full(obj, hr); |
2379 default: ShouldNotReachHere(); |
2386 default: ShouldNotReachHere(); |
2380 } |
2387 } |
2381 return false; // keep some compilers happy |
2388 return false; // keep some compilers happy |
2382 } |
2389 } |
2383 |
2390 |
2384 bool G1CollectedHeap::is_obj_dead_cond(const oop obj, |
2391 bool G1CollectedHeap::is_obj_dead_cond(const oop obj, |
2385 const VerifyOption vo) const { |
2392 const VerifyOption vo) const { |
2386 switch (vo) { |
2393 switch (vo) { |
2387 case VerifyOption_G1UsePrevMarking: return is_obj_dead(obj); |
2394 case VerifyOption_G1UsePrevMarking: return is_obj_dead(obj); |
2388 case VerifyOption_G1UseNextMarking: return is_obj_ill(obj); |
2395 case VerifyOption_G1UseNextMarking: return is_obj_ill(obj); |
2389 case VerifyOption_G1UseMarkWord: { |
2396 case VerifyOption_G1UseFullMarking: return is_obj_dead_full(obj); |
2390 HeapRegion* hr = _hrm.addr_to_region((HeapWord*)obj); |
|
2391 return !obj->is_gc_marked() && !hr->is_archive(); |
|
2392 } |
|
2393 default: ShouldNotReachHere(); |
2397 default: ShouldNotReachHere(); |
2394 } |
2398 } |
2395 return false; // keep some compilers happy |
2399 return false; // keep some compilers happy |
2396 } |
2400 } |
2397 |
2401 |