src/share/vm/gc_implementation/shared/gcUtil.hpp

Wed, 23 Dec 2009 09:23:54 -0800

author
ysr
date
Wed, 23 Dec 2009 09:23:54 -0800
changeset 1580
e018e6884bd8
parent 772
9ee9cf798b59
child 1907
c18cbe5936b8
permissions
-rw-r--r--

6631166: CMS: better heuristics when combatting fragmentation
Summary: Autonomic per-worker free block cache sizing, tunable coalition policies, fixes to per-size block statistics, retuned gain and bandwidth of some feedback loop filters to allow quicker reactivity to abrupt changes in ambient demand, and other heuristics to reduce fragmentation of the CMS old gen. Also tightened some assertions, including those related to locking.
Reviewed-by: jmasa

duke@435 1 /*
xdono@772 2 * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
duke@435 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
duke@435 20 * CA 95054 USA or visit www.sun.com if you need additional information or
duke@435 21 * have any questions.
duke@435 22 *
duke@435 23 */
duke@435 24
duke@435 25 // Catch-all file for utility classes
duke@435 26
duke@435 27 // A weighted average maintains a running, weighted average
duke@435 28 // of some float value (templates would be handy here if we
duke@435 29 // need different types).
duke@435 30 //
duke@435 31 // The average is adaptive in that we smooth it for the
duke@435 32 // initial samples; we don't use the weight until we have
duke@435 33 // enough samples for it to be meaningful.
duke@435 34 //
duke@435 35 // This serves as our best estimate of a future unknown.
duke@435 36 //
duke@435 37 class AdaptiveWeightedAverage : public CHeapObj {
duke@435 38 private:
duke@435 39 float _average; // The last computed average
duke@435 40 unsigned _sample_count; // How often we've sampled this average
duke@435 41 unsigned _weight; // The weight used to smooth the averages
duke@435 42 // A higher weight favors the most
duke@435 43 // recent data.
duke@435 44
duke@435 45 protected:
duke@435 46 float _last_sample; // The last value sampled.
duke@435 47
duke@435 48 void increment_count() { _sample_count++; }
duke@435 49 void set_average(float avg) { _average = avg; }
duke@435 50
duke@435 51 // Helper function, computes an adaptive weighted average
duke@435 52 // given a sample and the last average
duke@435 53 float compute_adaptive_average(float new_sample, float average);
duke@435 54
duke@435 55 public:
duke@435 56 // Input weight must be between 0 and 100
ysr@1580 57 AdaptiveWeightedAverage(unsigned weight, float avg = 0.0) :
ysr@1580 58 _average(avg), _sample_count(0), _weight(weight), _last_sample(0.0) {
duke@435 59 }
duke@435 60
iveresov@703 61 void clear() {
iveresov@703 62 _average = 0;
iveresov@703 63 _sample_count = 0;
iveresov@703 64 _last_sample = 0;
iveresov@703 65 }
iveresov@703 66
ysr@1580 67 // Useful for modifying static structures after startup.
ysr@1580 68 void modify(size_t avg, unsigned wt, bool force = false) {
ysr@1580 69 assert(force, "Are you sure you want to call this?");
ysr@1580 70 _average = (float)avg;
ysr@1580 71 _weight = wt;
ysr@1580 72 }
ysr@1580 73
duke@435 74 // Accessors
duke@435 75 float average() const { return _average; }
duke@435 76 unsigned weight() const { return _weight; }
duke@435 77 unsigned count() const { return _sample_count; }
duke@435 78 float last_sample() const { return _last_sample; }
duke@435 79
duke@435 80 // Update data with a new sample.
duke@435 81 void sample(float new_sample);
duke@435 82
duke@435 83 static inline float exp_avg(float avg, float sample,
duke@435 84 unsigned int weight) {
duke@435 85 assert(0 <= weight && weight <= 100, "weight must be a percent");
duke@435 86 return (100.0F - weight) * avg / 100.0F + weight * sample / 100.0F;
duke@435 87 }
duke@435 88 static inline size_t exp_avg(size_t avg, size_t sample,
duke@435 89 unsigned int weight) {
duke@435 90 // Convert to float and back to avoid integer overflow.
duke@435 91 return (size_t)exp_avg((float)avg, (float)sample, weight);
duke@435 92 }
ysr@1580 93
ysr@1580 94 // Printing
ysr@1580 95 void print_on(outputStream* st) const;
ysr@1580 96 void print() const;
duke@435 97 };
duke@435 98
duke@435 99
duke@435 100 // A weighted average that includes a deviation from the average,
duke@435 101 // some multiple of which is added to the average.
duke@435 102 //
duke@435 103 // This serves as our best estimate of an upper bound on a future
duke@435 104 // unknown.
duke@435 105 class AdaptivePaddedAverage : public AdaptiveWeightedAverage {
duke@435 106 private:
duke@435 107 float _padded_avg; // The last computed padded average
duke@435 108 float _deviation; // Running deviation from the average
duke@435 109 unsigned _padding; // A multiple which, added to the average,
duke@435 110 // gives us an upper bound guess.
duke@435 111
duke@435 112 protected:
duke@435 113 void set_padded_average(float avg) { _padded_avg = avg; }
duke@435 114 void set_deviation(float dev) { _deviation = dev; }
duke@435 115
duke@435 116 public:
duke@435 117 AdaptivePaddedAverage() :
duke@435 118 AdaptiveWeightedAverage(0),
duke@435 119 _padded_avg(0.0), _deviation(0.0), _padding(0) {}
duke@435 120
duke@435 121 AdaptivePaddedAverage(unsigned weight, unsigned padding) :
duke@435 122 AdaptiveWeightedAverage(weight),
duke@435 123 _padded_avg(0.0), _deviation(0.0), _padding(padding) {}
duke@435 124
duke@435 125 // Placement support
duke@435 126 void* operator new(size_t ignored, void* p) { return p; }
duke@435 127 // Allocator
duke@435 128 void* operator new(size_t size) { return CHeapObj::operator new(size); }
duke@435 129
duke@435 130 // Accessor
duke@435 131 float padded_average() const { return _padded_avg; }
duke@435 132 float deviation() const { return _deviation; }
duke@435 133 unsigned padding() const { return _padding; }
duke@435 134
iveresov@703 135 void clear() {
iveresov@703 136 AdaptiveWeightedAverage::clear();
iveresov@703 137 _padded_avg = 0;
iveresov@703 138 _deviation = 0;
iveresov@703 139 }
iveresov@703 140
duke@435 141 // Override
duke@435 142 void sample(float new_sample);
ysr@1580 143
ysr@1580 144 // Printing
ysr@1580 145 void print_on(outputStream* st) const;
ysr@1580 146 void print() const;
duke@435 147 };
duke@435 148
duke@435 149 // A weighted average that includes a deviation from the average,
duke@435 150 // some multiple of which is added to the average.
duke@435 151 //
duke@435 152 // This serves as our best estimate of an upper bound on a future
duke@435 153 // unknown.
duke@435 154 // A special sort of padded average: it doesn't update deviations
duke@435 155 // if the sample is zero. The average is allowed to change. We're
duke@435 156 // preventing the zero samples from drastically changing our padded
duke@435 157 // average.
duke@435 158 class AdaptivePaddedNoZeroDevAverage : public AdaptivePaddedAverage {
duke@435 159 public:
duke@435 160 AdaptivePaddedNoZeroDevAverage(unsigned weight, unsigned padding) :
duke@435 161 AdaptivePaddedAverage(weight, padding) {}
duke@435 162 // Override
duke@435 163 void sample(float new_sample);
ysr@1580 164
ysr@1580 165 // Printing
ysr@1580 166 void print_on(outputStream* st) const;
ysr@1580 167 void print() const;
duke@435 168 };
ysr@1580 169
duke@435 170 // Use a least squares fit to a set of data to generate a linear
duke@435 171 // equation.
duke@435 172 // y = intercept + slope * x
duke@435 173
duke@435 174 class LinearLeastSquareFit : public CHeapObj {
duke@435 175 double _sum_x; // sum of all independent data points x
duke@435 176 double _sum_x_squared; // sum of all independent data points x**2
duke@435 177 double _sum_y; // sum of all dependent data points y
duke@435 178 double _sum_xy; // sum of all x * y.
duke@435 179 double _intercept; // constant term
duke@435 180 double _slope; // slope
duke@435 181 // The weighted averages are not currently used but perhaps should
duke@435 182 // be used to get decaying averages.
duke@435 183 AdaptiveWeightedAverage _mean_x; // weighted mean of independent variable
duke@435 184 AdaptiveWeightedAverage _mean_y; // weighted mean of dependent variable
duke@435 185
duke@435 186 public:
duke@435 187 LinearLeastSquareFit(unsigned weight);
duke@435 188 void update(double x, double y);
duke@435 189 double y(double x);
duke@435 190 double slope() { return _slope; }
duke@435 191 // Methods to decide if a change in the dependent variable will
duke@435 192 // achive a desired goal. Note that these methods are not
duke@435 193 // complementary and both are needed.
duke@435 194 bool decrement_will_decrease();
duke@435 195 bool increment_will_decrease();
duke@435 196 };
duke@435 197
duke@435 198 class GCPauseTimer : StackObj {
duke@435 199 elapsedTimer* _timer;
duke@435 200 public:
duke@435 201 GCPauseTimer(elapsedTimer* timer) {
duke@435 202 _timer = timer;
duke@435 203 _timer->stop();
duke@435 204 }
duke@435 205 ~GCPauseTimer() {
duke@435 206 _timer->start();
duke@435 207 }
duke@435 208 };

mercurial