Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestChurnNotifications.java
64507 views
1
/*
2
* Copyright (c) 2018, 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.
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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
/*
26
* @test id=passive
27
* @summary Check that MX notifications are reported for all cycles
28
* @library /test/lib /
29
* @requires vm.gc.Shenandoah
30
*
31
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
32
* -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
33
* -XX:+ShenandoahDegeneratedGC -Dprecise=true
34
* TestChurnNotifications
35
*
36
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
37
* -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
38
* -XX:-ShenandoahDegeneratedGC -Dprecise=true
39
* TestChurnNotifications
40
*/
41
42
/*
43
* @test id=aggressive
44
* @summary Check that MX notifications are reported for all cycles
45
* @library /test/lib /
46
* @requires vm.gc.Shenandoah
47
*
48
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
49
* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
50
* -Dprecise=false
51
* TestChurnNotifications
52
*/
53
54
/*
55
* @test id=adaptive
56
* @summary Check that MX notifications are reported for all cycles
57
* @library /test/lib /
58
* @requires vm.gc.Shenandoah
59
*
60
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
61
* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
62
* -Dprecise=false
63
* TestChurnNotifications
64
*/
65
66
/*
67
* @test id=static
68
* @summary Check that MX notifications are reported for all cycles
69
* @library /test/lib /
70
* @requires vm.gc.Shenandoah
71
*
72
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
73
* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
74
* -Dprecise=false
75
* TestChurnNotifications
76
*/
77
78
/*
79
* @test id=compact
80
* @summary Check that MX notifications are reported for all cycles
81
* @library /test/lib /
82
* @requires vm.gc.Shenandoah
83
*
84
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
85
* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
86
* -Dprecise=false
87
* TestChurnNotifications
88
*/
89
90
/*
91
* @test id=iu
92
* @summary Check that MX notifications are reported for all cycles
93
* @library /test/lib /
94
* @requires vm.gc.Shenandoah
95
*
96
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
97
* -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive
98
* -Dprecise=false
99
* TestChurnNotifications
100
*
101
* @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
102
* -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu
103
* -Dprecise=false
104
* TestChurnNotifications
105
*/
106
107
import java.util.*;
108
import java.util.concurrent.atomic.*;
109
import javax.management.*;
110
import java.lang.management.*;
111
import javax.management.openmbean.*;
112
113
import jdk.test.lib.Utils;
114
115
import com.sun.management.GarbageCollectionNotificationInfo;
116
117
public class TestChurnNotifications {
118
119
static final long HEAP_MB = 128; // adjust for test configuration above
120
static final long TARGET_MB = Long.getLong("target", 2_000); // 2 Gb allocation
121
122
// Should we track the churn precisely?
123
// Precise tracking is only reliable when GC is fully stop-the-world. Otherwise,
124
// we cannot tell, looking at heap used before/after, what was the GC churn.
125
static final boolean PRECISE = Boolean.getBoolean("precise");
126
127
static final long M = 1024 * 1024;
128
129
static volatile Object sink;
130
131
public static void main(String[] args) throws Exception {
132
final long startTime = System.currentTimeMillis();
133
134
final AtomicLong churnBytes = new AtomicLong();
135
136
NotificationListener listener = new NotificationListener() {
137
@Override
138
public void handleNotification(Notification n, Object o) {
139
if (n.getType().equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
140
GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from((CompositeData) n.getUserData());
141
Map<String, MemoryUsage> mapBefore = info.getGcInfo().getMemoryUsageBeforeGc();
142
Map<String, MemoryUsage> mapAfter = info.getGcInfo().getMemoryUsageAfterGc();
143
144
MemoryUsage before = mapBefore.get("Shenandoah");
145
MemoryUsage after = mapAfter.get("Shenandoah");
146
147
if ((before != null) && (after != null)) {
148
long diff = before.getUsed() - after.getUsed();
149
if (diff > 0) {
150
churnBytes.addAndGet(diff);
151
}
152
}
153
}
154
}
155
};
156
157
for (GarbageCollectorMXBean bean : ManagementFactory.getGarbageCollectorMXBeans()) {
158
((NotificationEmitter) bean).addNotificationListener(listener, null, null);
159
}
160
161
final int size = 100_000;
162
long count = TARGET_MB * 1024 * 1024 / (16 + 4 * size);
163
164
long mem = count * (16 + 4 * size);
165
166
for (int c = 0; c < count; c++) {
167
sink = new int[size];
168
}
169
170
System.gc();
171
172
long minExpected = PRECISE ? (mem - HEAP_MB * 1024 * 1024) : 1;
173
long maxExpected = mem + HEAP_MB * 1024 * 1024;
174
long actual = 0;
175
176
// Look at test timeout to figure out how long we can wait without breaking into timeout.
177
// Default to 1/4 of the remaining time in 1s steps.
178
final long STEP_MS = 1000;
179
long spentTime = System.currentTimeMillis() - startTime;
180
long maxTries = (Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT) - spentTime) / STEP_MS / 4;
181
182
// Wait until enough notifications are accrued to match minimum boundary.
183
long tries = 0;
184
while (tries++ < maxTries) {
185
actual = churnBytes.get();
186
if (minExpected <= actual) {
187
// Wait some more to test if we are breaking the maximum boundary.
188
Thread.sleep(5000);
189
actual = churnBytes.get();
190
break;
191
}
192
Thread.sleep(STEP_MS);
193
}
194
195
String msg = "Expected = [" + minExpected / M + "; " + maxExpected / M + "] (" + mem / M + "), actual = " + actual / M;
196
if (minExpected <= actual && actual <= maxExpected) {
197
System.out.println(msg);
198
} else {
199
throw new IllegalStateException(msg);
200
}
201
}
202
}
203
204