1.1 --- a/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp Wed Jan 18 09:50:16 2012 -0800 1.2 +++ b/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp Wed Feb 15 13:06:53 2012 -0500 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -28,28 +28,6 @@ 1.11 #include "gc_implementation/g1/heapRegion.hpp" 1.12 #include "utilities/growableArray.hpp" 1.13 1.14 -// We need to sort heap regions by collection desirability. 1.15 -// This sorting is currently done in two "stages". An initial sort is 1.16 -// done following a cleanup pause as soon as all of the marked but 1.17 -// non-empty regions have been identified and the completely empty 1.18 -// ones reclaimed. 1.19 -// This gives us a global sort on a GC efficiency metric 1.20 -// based on predictive data available at that time. However, 1.21 -// any of these regions that are collected will only be collected 1.22 -// during a future GC pause, by which time it is possible that newer 1.23 -// data might allow us to revise and/or refine the earlier 1.24 -// pause predictions, leading to changes in expected gc efficiency 1.25 -// order. To somewhat mitigate this obsolescence, more so in the 1.26 -// case of regions towards the end of the list, which will be 1.27 -// picked later, these pre-sorted regions from the _markedRegions 1.28 -// array are not used as is, but a small prefix thereof is 1.29 -// insertion-sorted again into a small cache, based on more 1.30 -// recent remembered set information. Regions are then drawn 1.31 -// from this cache to construct the collection set at each 1.32 -// incremental GC. 1.33 -// This scheme and/or its implementation may be subject to 1.34 -// revision in the future. 1.35 - 1.36 class CSetChooserCache VALUE_OBJ_CLASS_SPEC { 1.37 private: 1.38 enum { 1.39 @@ -103,24 +81,82 @@ 1.40 class CollectionSetChooser: public CHeapObj { 1.41 1.42 GrowableArray<HeapRegion*> _markedRegions; 1.43 - int _curMarkedIndex; 1.44 - int _numMarkedRegions; 1.45 + 1.46 + // The index of the next candidate old region to be considered for 1.47 + // addition to the CSet. 1.48 + int _curr_index; 1.49 + 1.50 + // The number of candidate old regions added to the CSet chooser. 1.51 + int _length; 1.52 + 1.53 CSetChooserCache _cache; 1.54 + jint _first_par_unreserved_idx; 1.55 1.56 - // True iff last collection pause ran of out new "age 0" regions, and 1.57 - // returned an "age 1" region. 1.58 - bool _unmarked_age_1_returned_as_new; 1.59 + // If a region has more live bytes than this threshold, it will not 1.60 + // be added to the CSet chooser and will not be a candidate for 1.61 + // collection. 1.62 + size_t _regionLiveThresholdBytes; 1.63 1.64 - jint _first_par_unreserved_idx; 1.65 + // The sum of reclaimable bytes over all the regions in the CSet chooser. 1.66 + size_t _remainingReclaimableBytes; 1.67 1.68 public: 1.69 1.70 - HeapRegion* getNextMarkedRegion(double time_so_far, double avg_prediction); 1.71 + // Return the current candidate region to be considered for 1.72 + // collection without removing it from the CSet chooser. 1.73 + HeapRegion* peek() { 1.74 + HeapRegion* res = NULL; 1.75 + if (_curr_index < _length) { 1.76 + res = _markedRegions.at(_curr_index); 1.77 + assert(res != NULL, 1.78 + err_msg("Unexpected NULL hr in _markedRegions at index %d", 1.79 + _curr_index)); 1.80 + } 1.81 + return res; 1.82 + } 1.83 + 1.84 + // Remove the given region from the CSet chooser and move to the 1.85 + // next one. The given region should be the current candidate region 1.86 + // in the CSet chooser. 1.87 + void remove_and_move_to_next(HeapRegion* hr) { 1.88 + assert(hr != NULL, "pre-condition"); 1.89 + assert(_curr_index < _length, "pre-condition"); 1.90 + assert(_markedRegions.at(_curr_index) == hr, "pre-condition"); 1.91 + hr->set_sort_index(-1); 1.92 + _markedRegions.at_put(_curr_index, NULL); 1.93 + assert(hr->reclaimable_bytes() <= _remainingReclaimableBytes, 1.94 + err_msg("remaining reclaimable bytes inconsistent " 1.95 + "from region: "SIZE_FORMAT" remaining: "SIZE_FORMAT, 1.96 + hr->reclaimable_bytes(), _remainingReclaimableBytes)); 1.97 + _remainingReclaimableBytes -= hr->reclaimable_bytes(); 1.98 + _curr_index += 1; 1.99 + } 1.100 1.101 CollectionSetChooser(); 1.102 1.103 void sortMarkedHeapRegions(); 1.104 void fillCache(); 1.105 + 1.106 + // Determine whether to add the given region to the CSet chooser or 1.107 + // not. Currently, we skip humongous regions (we never add them to 1.108 + // the CSet, we only reclaim them during cleanup) and regions whose 1.109 + // live bytes are over the threshold. 1.110 + bool shouldAdd(HeapRegion* hr) { 1.111 + assert(hr->is_marked(), "pre-condition"); 1.112 + assert(!hr->is_young(), "should never consider young regions"); 1.113 + return !hr->isHumongous() && 1.114 + hr->live_bytes() < _regionLiveThresholdBytes; 1.115 + } 1.116 + 1.117 + // Calculate the minimum number of old regions we'll add to the CSet 1.118 + // during a mixed GC. 1.119 + size_t calcMinOldCSetLength(); 1.120 + 1.121 + // Calculate the maximum number of old regions we'll add to the CSet 1.122 + // during a mixed GC. 1.123 + size_t calcMaxOldCSetLength(); 1.124 + 1.125 + // Serial version. 1.126 void addMarkedHeapRegion(HeapRegion *hr); 1.127 1.128 // Must be called before calls to getParMarkedHeapRegionChunk. 1.129 @@ -133,14 +169,21 @@ 1.130 // Set the marked array entry at index to hr. Careful to claim the index 1.131 // first if in parallel. 1.132 void setMarkedHeapRegion(jint index, HeapRegion* hr); 1.133 - // Atomically increment the number of claimed regions by "inc_by". 1.134 - void incNumMarkedHeapRegions(jint inc_by); 1.135 + // Atomically increment the number of added regions by region_num 1.136 + // and the amount of reclaimable bytes by reclaimable_bytes. 1.137 + void updateTotals(jint region_num, size_t reclaimable_bytes); 1.138 1.139 void clearMarkedHeapRegions(); 1.140 1.141 - void updateAfterFullCollection(); 1.142 + // Return the number of candidate regions that remain to be collected. 1.143 + size_t remainingRegions() { return _length - _curr_index; } 1.144 1.145 - bool unmarked_age_1_returned_as_new() { return _unmarked_age_1_returned_as_new; } 1.146 + // Determine whether the CSet chooser has more candidate regions or not. 1.147 + bool isEmpty() { return remainingRegions() == 0; } 1.148 + 1.149 + // Return the reclaimable bytes that remain to be collected on 1.150 + // all the candidate regions in the CSet chooser. 1.151 + size_t remainingReclaimableBytes () { return _remainingReclaimableBytes; } 1.152 1.153 // Returns true if the used portion of "_markedRegions" is properly 1.154 // sorted, otherwise asserts false. 1.155 @@ -148,9 +191,17 @@ 1.156 bool verify(void); 1.157 bool regionProperlyOrdered(HeapRegion* r) { 1.158 int si = r->sort_index(); 1.159 - return (si == -1) || 1.160 - (si > -1 && _markedRegions.at(si) == r) || 1.161 - (si < -1 && _cache.region_in_cache(r)); 1.162 + if (si > -1) { 1.163 + guarantee(_curr_index <= si && si < _length, 1.164 + err_msg("curr: %d sort index: %d: length: %d", 1.165 + _curr_index, si, _length)); 1.166 + guarantee(_markedRegions.at(si) == r, 1.167 + err_msg("sort index: %d at: "PTR_FORMAT" r: "PTR_FORMAT, 1.168 + si, _markedRegions.at(si), r)); 1.169 + } else { 1.170 + guarantee(si == -1, err_msg("sort index: %d", si)); 1.171 + } 1.172 + return true; 1.173 } 1.174 #endif 1.175