src/hotspot/share/gc/g1/g1CollectionSet.cpp
changeset 53703 24341625d8f2
parent 52897 495c05ee2a9a
child 54465 c4f16445675a
equal deleted inserted replaced
53702:50a5d0353570 53703:24341625d8f2
     1 /*
     1 /*
     2  * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2016, 2019, Oracle and/or its affiliates. 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.
    23  */
    23  */
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 #include "gc/g1/g1CollectedHeap.inline.hpp"
    26 #include "gc/g1/g1CollectedHeap.inline.hpp"
    27 #include "gc/g1/g1CollectionSet.hpp"
    27 #include "gc/g1/g1CollectionSet.hpp"
       
    28 #include "gc/g1/g1CollectionSetCandidates.hpp"
    28 #include "gc/g1/g1CollectorState.hpp"
    29 #include "gc/g1/g1CollectorState.hpp"
    29 #include "gc/g1/g1ParScanThreadState.hpp"
    30 #include "gc/g1/g1ParScanThreadState.hpp"
    30 #include "gc/g1/g1Policy.hpp"
    31 #include "gc/g1/g1Policy.hpp"
    31 #include "gc/g1/heapRegion.inline.hpp"
    32 #include "gc/g1/heapRegion.inline.hpp"
    32 #include "gc/g1/heapRegionRemSet.hpp"
    33 #include "gc/g1/heapRegionRemSet.hpp"
    42 
    43 
    43 G1GCPhaseTimes* G1CollectionSet::phase_times() {
    44 G1GCPhaseTimes* G1CollectionSet::phase_times() {
    44   return _policy->phase_times();
    45   return _policy->phase_times();
    45 }
    46 }
    46 
    47 
    47 CollectionSetChooser* G1CollectionSet::cset_chooser() {
       
    48   return _cset_chooser;
       
    49 }
       
    50 
       
    51 double G1CollectionSet::predict_region_elapsed_time_ms(HeapRegion* hr) {
    48 double G1CollectionSet::predict_region_elapsed_time_ms(HeapRegion* hr) {
    52   return _policy->predict_region_elapsed_time_ms(hr, collector_state()->in_young_only_phase());
    49   return _policy->predict_region_elapsed_time_ms(hr, collector_state()->in_young_only_phase());
    53 }
    50 }
    54 
    51 
    55 G1CollectionSet::G1CollectionSet(G1CollectedHeap* g1h, G1Policy* policy) :
    52 G1CollectionSet::G1CollectionSet(G1CollectedHeap* g1h, G1Policy* policy) :
    56   _g1h(g1h),
    53   _g1h(g1h),
    57   _policy(policy),
    54   _policy(policy),
    58   _cset_chooser(new CollectionSetChooser()),
    55   _candidates(NULL),
    59   _eden_region_length(0),
    56   _eden_region_length(0),
    60   _survivor_region_length(0),
    57   _survivor_region_length(0),
    61   _old_region_length(0),
    58   _old_region_length(0),
    62   _collection_set_regions(NULL),
    59   _collection_set_regions(NULL),
    63   _collection_set_cur_length(0),
    60   _collection_set_cur_length(0),
    78 G1CollectionSet::~G1CollectionSet() {
    75 G1CollectionSet::~G1CollectionSet() {
    79   if (_collection_set_regions != NULL) {
    76   if (_collection_set_regions != NULL) {
    80     FREE_C_HEAP_ARRAY(uint, _collection_set_regions);
    77     FREE_C_HEAP_ARRAY(uint, _collection_set_regions);
    81   }
    78   }
    82   free_optional_regions();
    79   free_optional_regions();
    83   delete _cset_chooser;
    80   clear_candidates();
    84 }
    81 }
    85 
    82 
    86 void G1CollectionSet::init_region_lengths(uint eden_cset_region_length,
    83 void G1CollectionSet::init_region_lengths(uint eden_cset_region_length,
    87                                           uint survivor_cset_region_length) {
    84                                           uint survivor_cset_region_length) {
    88   assert_at_safepoint_on_vm_thread();
    85   assert_at_safepoint_on_vm_thread();
   116   _optional_region_max_length = 0;
   113   _optional_region_max_length = 0;
   117   if (_optional_regions != NULL) {
   114   if (_optional_regions != NULL) {
   118     FREE_C_HEAP_ARRAY(HeapRegion*, _optional_regions);
   115     FREE_C_HEAP_ARRAY(HeapRegion*, _optional_regions);
   119     _optional_regions = NULL;
   116     _optional_regions = NULL;
   120   }
   117   }
       
   118 }
       
   119 
       
   120 void G1CollectionSet::clear_candidates() {
       
   121   delete _candidates;
       
   122   _candidates = NULL;
   121 }
   123 }
   122 
   124 
   123 void G1CollectionSet::set_recorded_rs_lengths(size_t rs_lengths) {
   125 void G1CollectionSet::set_recorded_rs_lengths(size_t rs_lengths) {
   124   _recorded_rs_lengths = rs_lengths;
   126   _recorded_rs_lengths = rs_lengths;
   125 }
   127 }
   437 
   439 
   438   return time_remaining_ms;
   440   return time_remaining_ms;
   439 }
   441 }
   440 
   442 
   441 void G1CollectionSet::add_as_old(HeapRegion* hr) {
   443 void G1CollectionSet::add_as_old(HeapRegion* hr) {
   442   cset_chooser()->pop(); // already have region via peek()
   444   candidates()->pop_front(); // already have region via peek()
   443   _g1h->old_set_remove(hr);
   445   _g1h->old_set_remove(hr);
   444   add_old_region(hr);
   446   add_old_region(hr);
   445 }
   447 }
   446 
   448 
   447 void G1CollectionSet::add_as_optional(HeapRegion* hr) {
   449 void G1CollectionSet::add_as_optional(HeapRegion* hr) {
   448   assert(_optional_regions != NULL, "Must not be called before array is allocated");
   450   assert(_optional_regions != NULL, "Must not be called before array is allocated");
   449   cset_chooser()->pop(); // already have region via peek()
   451   candidates()->pop_front(); // already have region via peek()
   450   _g1h->old_set_remove(hr);
   452   _g1h->old_set_remove(hr);
   451   add_optional_region(hr);
   453   add_optional_region(hr);
   452 }
   454 }
   453 
   455 
   454 bool G1CollectionSet::optional_is_full() {
   456 bool G1CollectionSet::optional_is_full() {
   478   double predicted_optional_time_ms = 0.0;
   480   double predicted_optional_time_ms = 0.0;
   479   double optional_threshold_ms = time_remaining_ms * _policy->optional_prediction_fraction();
   481   double optional_threshold_ms = time_remaining_ms * _policy->optional_prediction_fraction();
   480   uint expensive_region_num = 0;
   482   uint expensive_region_num = 0;
   481 
   483 
   482   if (collector_state()->in_mixed_phase()) {
   484   if (collector_state()->in_mixed_phase()) {
   483     cset_chooser()->verify();
   485     candidates()->verify();
   484     const uint min_old_cset_length = _policy->calc_min_old_cset_length();
   486     const uint min_old_cset_length = _policy->calc_min_old_cset_length();
   485     const uint max_old_cset_length = MAX2(min_old_cset_length, _policy->calc_max_old_cset_length());
   487     const uint max_old_cset_length = MAX2(min_old_cset_length, _policy->calc_max_old_cset_length());
   486     bool check_time_remaining = _policy->adaptive_young_list_length();
   488     bool check_time_remaining = _policy->adaptive_young_list_length();
   487 
   489 
   488     initialize_optional(max_old_cset_length - min_old_cset_length);
   490     initialize_optional(max_old_cset_length - min_old_cset_length);
   489     log_debug(gc, ergo, cset)("Start adding old regions for mixed gc. min %u regions, max %u regions, "
   491     log_debug(gc, ergo, cset)("Start adding old regions for mixed gc. min %u regions, max %u regions, "
   490                               "time remaining %1.2fms, optional threshold %1.2fms",
   492                               "time remaining %1.2fms, optional threshold %1.2fms",
   491                               min_old_cset_length, max_old_cset_length, time_remaining_ms, optional_threshold_ms);
   493                               min_old_cset_length, max_old_cset_length, time_remaining_ms, optional_threshold_ms);
   492 
   494 
   493     HeapRegion* hr = cset_chooser()->peek();
   495     HeapRegion* hr = candidates()->peek_front();
   494     while (hr != NULL) {
   496     while (hr != NULL) {
   495       if (old_region_length() + optional_region_length() >= max_old_cset_length) {
   497       if (old_region_length() + optional_region_length() >= max_old_cset_length) {
   496         // Added maximum number of old regions to the CSet.
   498         // Added maximum number of old regions to the CSet.
   497         log_debug(gc, ergo, cset)("Finish adding old regions to CSet (old CSet region num reached max). "
   499         log_debug(gc, ergo, cset)("Finish adding old regions to CSet (old CSet region num reached max). "
   498                                   "old %u regions, optional %u regions",
   500                                   "old %u regions, optional %u regions",
   500         break;
   502         break;
   501       }
   503       }
   502 
   504 
   503       // Stop adding regions if the remaining reclaimable space is
   505       // Stop adding regions if the remaining reclaimable space is
   504       // not above G1HeapWastePercent.
   506       // not above G1HeapWastePercent.
   505       size_t reclaimable_bytes = cset_chooser()->remaining_reclaimable_bytes();
   507       size_t reclaimable_bytes = candidates()->remaining_reclaimable_bytes();
   506       double reclaimable_percent = _policy->reclaimable_bytes_percent(reclaimable_bytes);
   508       double reclaimable_percent = _policy->reclaimable_bytes_percent(reclaimable_bytes);
   507       double threshold = (double) G1HeapWastePercent;
   509       double threshold = (double) G1HeapWastePercent;
   508       if (reclaimable_percent <= threshold) {
   510       if (reclaimable_percent <= threshold) {
   509         // We've added enough old regions that the amount of uncollected
   511         // We've added enough old regions that the amount of uncollected
   510         // reclaimable space is at or below the waste threshold. Stop
   512         // reclaimable space is at or below the waste threshold. Stop
   549         } else {
   551         } else {
   550           log_debug(gc, ergo, cset)("Finish adding old regions to CSet (predicted time is too high).");
   552           log_debug(gc, ergo, cset)("Finish adding old regions to CSet (predicted time is too high).");
   551           break;
   553           break;
   552         }
   554         }
   553       }
   555       }
   554       hr = cset_chooser()->peek();
   556       hr = candidates()->peek_front();
   555     }
   557     }
   556     if (hr == NULL) {
   558     if (hr == NULL) {
   557       log_debug(gc, ergo, cset)("Finish adding old regions to CSet (candidate old regions not available)");
   559       log_debug(gc, ergo, cset)("Finish adding old regions to CSet (candidate old regions not available)");
   558     }
   560     }
   559 
   561 
   560     cset_chooser()->verify();
   562     candidates()->verify();
   561   }
   563   }
   562 
   564 
   563   stop_incremental_building();
   565   stop_incremental_building();
   564 
   566 
   565   log_debug(gc, ergo, cset)("Finish choosing CSet regions old: %u, optional: %u, "
   567   log_debug(gc, ergo, cset)("Finish choosing CSet regions old: %u, optional: %u, "
   628 }
   630 }
   629 
   631 
   630 G1OptionalCSet::~G1OptionalCSet() {
   632 G1OptionalCSet::~G1OptionalCSet() {
   631   G1CollectedHeap* g1h = G1CollectedHeap::heap();
   633   G1CollectedHeap* g1h = G1CollectedHeap::heap();
   632   while (!is_empty()) {
   634   while (!is_empty()) {
   633     // We want to return regions not evacuated to the
   635     // We want to return regions not evacuated to the collection set candidates
   634     // chooser in reverse order to maintain the old order.
   636     // in reverse order to maintain the old order.
   635     HeapRegion* hr = _cset->remove_last_optional_region();
   637     HeapRegion* hr = _cset->remove_last_optional_region();
   636     assert(hr != NULL, "Should be valid region left");
   638     assert(hr != NULL, "Should be valid region left");
   637     _pset->record_unused_optional_region(hr);
   639     _pset->record_unused_optional_region(hr);
   638     g1h->old_set_add(hr);
   640     g1h->old_set_add(hr);
   639     g1h->clear_in_cset(hr);
   641     g1h->clear_in_cset(hr);
   640     hr->set_index_in_opt_cset(InvalidCSetIndex);
   642     hr->set_index_in_opt_cset(InvalidCSetIndex);
   641     _cset->cset_chooser()->push(hr);
   643     _cset->candidates()->push_front(hr);
   642   }
   644   }
   643   _cset->free_optional_regions();
   645   _cset->free_optional_regions();
   644 }
   646 }
   645 
   647 
   646 uint G1OptionalCSet::size() {
   648 uint G1OptionalCSet::size() {