annotate src/share/vm/gc_implementation/shared/gcUtil.hpp @ 1145:e018e6884bd8

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