Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/shared/allocationStats.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 | d1605aabd0a1 |
children | c18cbe5936b8 |
rev | line source |
---|---|
0 | 1 /* |
196 | 2 * Copyright 2001-2008 Sun Microsystems, Inc. All Rights Reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
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 | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 class AllocationStats VALUE_OBJ_CLASS_SPEC { | |
26 // A duration threshold (in ms) used to filter | |
27 // possibly unreliable samples. | |
28 static float _threshold; | |
29 | |
30 // We measure the demand between the end of the previous sweep and | |
31 // beginning of this sweep: | |
32 // Count(end_last_sweep) - Count(start_this_sweep) | |
33 // + splitBirths(between) - splitDeaths(between) | |
1145
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
34 // The above number divided by the time since the end of the |
0 | 35 // previous sweep gives us a time rate of demand for blocks |
36 // of this size. We compute a padded average of this rate as | |
37 // our current estimate for the time rate of demand for blocks | |
38 // of this size. Similarly, we keep a padded average for the time | |
39 // between sweeps. Our current estimate for demand for blocks of | |
40 // this size is then simply computed as the product of these two | |
41 // estimates. | |
42 AdaptivePaddedAverage _demand_rate_estimate; | |
43 | |
1145
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
44 ssize_t _desired; // Demand stimate computed as described above |
0 | 45 ssize_t _coalDesired; // desired +/- small-percent for tuning coalescing |
46 | |
47 ssize_t _surplus; // count - (desired +/- small-percent), | |
48 // used to tune splitting in best fit | |
49 ssize_t _bfrSurp; // surplus at start of current sweep | |
50 ssize_t _prevSweep; // count from end of previous sweep | |
51 ssize_t _beforeSweep; // count from before current sweep | |
52 ssize_t _coalBirths; // additional chunks from coalescing | |
53 ssize_t _coalDeaths; // loss from coalescing | |
54 ssize_t _splitBirths; // additional chunks from splitting | |
55 ssize_t _splitDeaths; // loss from splitting | |
1145
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
56 size_t _returnedBytes; // number of bytes returned to list. |
0 | 57 public: |
1145
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
58 void initialize(bool split_birth = false) { |
0 | 59 AdaptivePaddedAverage* dummy = |
60 new (&_demand_rate_estimate) AdaptivePaddedAverage(CMS_FLSWeight, | |
61 CMS_FLSPadding); | |
62 _desired = 0; | |
63 _coalDesired = 0; | |
64 _surplus = 0; | |
65 _bfrSurp = 0; | |
66 _prevSweep = 0; | |
67 _beforeSweep = 0; | |
68 _coalBirths = 0; | |
69 _coalDeaths = 0; | |
1145
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
70 _splitBirths = split_birth? 1 : 0; |
0 | 71 _splitDeaths = 0; |
72 _returnedBytes = 0; | |
73 } | |
74 | |
75 AllocationStats() { | |
76 initialize(); | |
77 } | |
1145
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
78 |
0 | 79 // The rate estimate is in blocks per second. |
80 void compute_desired(size_t count, | |
81 float inter_sweep_current, | |
1145
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
82 float inter_sweep_estimate, |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
83 float intra_sweep_estimate) { |
0 | 84 // If the latest inter-sweep time is below our granularity |
85 // of measurement, we may call in here with | |
86 // inter_sweep_current == 0. However, even for suitably small | |
87 // but non-zero inter-sweep durations, we may not trust the accuracy | |
88 // of accumulated data, since it has not been "integrated" | |
89 // (read "low-pass-filtered") long enough, and would be | |
90 // vulnerable to noisy glitches. In such cases, we | |
91 // ignore the current sample and use currently available | |
92 // historical estimates. | |
1145
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
93 // XXX NEEDS TO BE FIXED |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
94 // assert(prevSweep() + splitBirths() >= splitDeaths() + (ssize_t)count, "Conservation Principle"); |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
95 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
96 // "Total Stock" "Not used at this block size" |
0 | 97 if (inter_sweep_current > _threshold) { |
1145
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
98 ssize_t demand = prevSweep() - (ssize_t)count + splitBirths() - splitDeaths(); |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
99 // XXX NEEDS TO BE FIXED |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
100 // assert(demand >= 0, "Demand should be non-negative"); |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
101 // Defensive: adjust for imprecision in event counting |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
102 if (demand < 0) { |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
103 demand = 0; |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
104 } |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
105 float old_rate = _demand_rate_estimate.padded_average(); |
0 | 106 float rate = ((float)demand)/inter_sweep_current; |
107 _demand_rate_estimate.sample(rate); | |
1145
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
108 float new_rate = _demand_rate_estimate.padded_average(); |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
109 ssize_t old_desired = _desired; |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
110 _desired = (ssize_t)(new_rate * (inter_sweep_estimate |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
111 + CMSExtrapolateSweep |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
112 ? intra_sweep_estimate |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
113 : 0.0)); |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
114 if (PrintFLSStatistics > 1) { |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
115 gclog_or_tty->print_cr("demand: %d, old_rate: %f, current_rate: %f, new_rate: %f, old_desired: %d, new_desired: %d", |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
116 demand, old_rate, rate, new_rate, old_desired, _desired); |
e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
ysr
parents:
196
diff
changeset
|
117 } |
0 | 118 } |
119 } | |
120 | |
121 ssize_t desired() const { return _desired; } | |
12
6432c3bb6240
6668743: CMS: Consolidate block statistics reporting code
ysr
parents:
0
diff
changeset
|
122 void set_desired(ssize_t v) { _desired = v; } |
6432c3bb6240
6668743: CMS: Consolidate block statistics reporting code
ysr
parents:
0
diff
changeset
|
123 |
0 | 124 ssize_t coalDesired() const { return _coalDesired; } |
125 void set_coalDesired(ssize_t v) { _coalDesired = v; } | |
126 | |
127 ssize_t surplus() const { return _surplus; } | |
128 void set_surplus(ssize_t v) { _surplus = v; } | |
129 void increment_surplus() { _surplus++; } | |
130 void decrement_surplus() { _surplus--; } | |
131 | |
132 ssize_t bfrSurp() const { return _bfrSurp; } | |
133 void set_bfrSurp(ssize_t v) { _bfrSurp = v; } | |
134 ssize_t prevSweep() const { return _prevSweep; } | |
135 void set_prevSweep(ssize_t v) { _prevSweep = v; } | |
136 ssize_t beforeSweep() const { return _beforeSweep; } | |
137 void set_beforeSweep(ssize_t v) { _beforeSweep = v; } | |
138 | |
139 ssize_t coalBirths() const { return _coalBirths; } | |
140 void set_coalBirths(ssize_t v) { _coalBirths = v; } | |
141 void increment_coalBirths() { _coalBirths++; } | |
142 | |
143 ssize_t coalDeaths() const { return _coalDeaths; } | |
144 void set_coalDeaths(ssize_t v) { _coalDeaths = v; } | |
145 void increment_coalDeaths() { _coalDeaths++; } | |
146 | |
147 ssize_t splitBirths() const { return _splitBirths; } | |
148 void set_splitBirths(ssize_t v) { _splitBirths = v; } | |
149 void increment_splitBirths() { _splitBirths++; } | |
150 | |
151 ssize_t splitDeaths() const { return _splitDeaths; } | |
152 void set_splitDeaths(ssize_t v) { _splitDeaths = v; } | |
153 void increment_splitDeaths() { _splitDeaths++; } | |
154 | |
155 NOT_PRODUCT( | |
156 size_t returnedBytes() const { return _returnedBytes; } | |
157 void set_returnedBytes(size_t v) { _returnedBytes = v; } | |
158 ) | |
159 }; |