7903368: JMH: GC profiler misreports allocation and churn rates · openjdk/jmh@e7b1218 (original) (raw)
``
1
`+
/*
`
``
2
`+
- Copyright (c) 2022, Red Hat, Inc. All rights reserved.
`
``
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. Oracle designates this
`
``
8
`+
- particular file as subject to the "Classpath" exception as provided
`
``
9
`+
- by Oracle in the LICENSE file that accompanied this code.
`
``
10
`+
`
``
11
`+
- This code is distributed in the hope that it will be useful, but WITHOUT
`
``
12
`+
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
`
``
13
`+
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
`
``
14
`+
- version 2 for more details (a copy is included in the LICENSE file that
`
``
15
`+
- accompanied this code).
`
``
16
`+
`
``
17
`+
- You should have received a copy of the GNU General Public License version
`
``
18
`+
- 2 along with this work; if not, write to the Free Software Foundation,
`
``
19
`+
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
`
``
20
`+
`
``
21
`+
- Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
`
``
22
`+
- or visit www.oracle.com if you need additional information or have any
`
``
23
`+
- questions.
`
``
24
`+
*/
`
``
25
`+
package org.openjdk.jmh.it.profilers;
`
``
26
+
``
27
`+
import org.junit.Assert;
`
``
28
`+
import org.junit.Test;
`
``
29
`+
import org.openjdk.jmh.annotations.*;
`
``
30
`+
import org.openjdk.jmh.it.Fixtures;
`
``
31
`+
import org.openjdk.jmh.profile.GCProfiler;
`
``
32
`+
import org.openjdk.jmh.results.Result;
`
``
33
`+
import org.openjdk.jmh.results.RunResult;
`
``
34
`+
import org.openjdk.jmh.runner.Runner;
`
``
35
`+
import org.openjdk.jmh.runner.RunnerException;
`
``
36
`+
import org.openjdk.jmh.runner.options.Options;
`
``
37
`+
import org.openjdk.jmh.runner.options.OptionsBuilder;
`
``
38
+
``
39
`+
import java.util.Collection;
`
``
40
`+
import java.util.Map;
`
``
41
`+
import java.util.concurrent.TimeUnit;
`
``
42
+
``
43
`+
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
`
``
44
`+
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
`
``
45
`+
@Fork(1)
`
``
46
`+
@BenchmarkMode(Mode.Throughput)
`
``
47
`+
@OutputTimeUnit(TimeUnit.SECONDS)
`
``
48
`+
public class GCProfilerAllocRateTest {
`
``
49
+
``
50
`+
@Benchmark
`
``
51
`+
public Object allocate() {
`
``
52
`+
return new byte[1000];
`
``
53
`+
}
`
``
54
+
``
55
`+
@Test
`
``
56
`+
public void test() throws RunnerException {
`
``
57
`+
Options opts = new OptionsBuilder()
`
``
58
`+
.include(Fixtures.getTestMask(this.getClass()))
`
``
59
`+
.addProfiler(GCProfiler.class)
`
``
60
`+
.build();
`
``
61
+
``
62
`+
RunResult rr = new Runner(opts).runSingle();
`
``
63
+
``
64
`+
double opsPerSec = rr.getPrimaryResult().getScore();
`
``
65
+
``
66
`+
Map<String, Result> sr = rr.getSecondaryResults();
`
``
67
`+
double allocRateMB = sr.get("·gc.alloc.rate").getScore();
`
``
68
`+
double allocRateNormB = sr.get("·gc.alloc.rate.norm").getScore();
`
``
69
`+
double allocRatePrimaryMB = opsPerSec * allocRateNormB / 1024 / 1024;
`
``
70
+
``
71
`+
// Allow 20% slack
`
``
72
`+
if (Math.abs(1 - allocRatePrimaryMB / allocRateMB) > 0.2) {
`
``
73
`+
Assert.fail("Allocation rates disagree. " +
`
``
74
`+
"Reported by profiler: " + allocRateMB +
`
``
75
`+
", computed from primary score: " + allocRatePrimaryMB);
`
``
76
`+
}
`
``
77
`+
}
`
``
78
`+
}
`