Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/metaspace/shrink_grow/ShrinkGrowTest/ShrinkGrowTest.java
41155 views
1
/*
2
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. 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
27
*
28
* @bug 8217432
29
* @summary converted from VM Testbase metaspace/shrink_grow/ShrinkGrowTest.
30
*
31
* @requires vm.opt.final.ClassUnloading
32
* @library /vmTestbase /test/lib
33
* @run main/othervm
34
* -XX:MetaspaceSize=10m
35
* -XX:MaxMetaspaceSize=20m
36
* -Xlog:gc*:gc.log
37
* metaspace.shrink_grow.ShrinkGrowTest.ShrinkGrowTest
38
*/
39
40
package metaspace.shrink_grow.ShrinkGrowTest;
41
42
import java.lang.reflect.InvocationHandler;
43
import java.lang.reflect.Method;
44
import java.lang.reflect.Proxy;
45
import java.lang.management.ManagementFactory;
46
import java.lang.management.MemoryPoolMXBean;
47
import java.net.URL;
48
import java.net.URLClassLoader;
49
import java.util.HashMap;
50
import java.util.Map;
51
52
/**
53
* This is the main test in the metaspace shrink/grow series.
54
*
55
* It tries to allocate all available metespace (loads new classes and keeps
56
* them in map), then checks that loading new classes causes OOM.
57
* After that it does cleanup loaded classes and then expect the new classes
58
* could be loaded again.
59
*
60
* <b>Note</b>: Don't forget to limit the metaspace size by giving
61
* -XX:MaxMetaspaceSize=100k vm option.
62
*/
63
public class ShrinkGrowTest {
64
65
/**
66
* Dead classes storage.
67
*/
68
private final Map<String, ShrinkGrowTest.Foo> loadedClasses = new HashMap<>();
69
70
private static int counter = 0;
71
72
private String errorMessage = "not completed";
73
74
// thread id to distinguish threads in output
75
private final String whoAmI;
76
77
// the limit of classes to load expecting OOM
78
private final int maxClassesToLoad;
79
80
public static void main(String[] args) {
81
String name = args.length > 0 ? args[0] : "singleTest" ;
82
new ShrinkGrowTest(name, 20000).run();
83
}
84
85
/**
86
* @param name - thread id used in logging
87
* @param classesToLoad - the limit of classes to load expecting OOM
88
*/
89
public ShrinkGrowTest(String name, int classesToLoad) {
90
whoAmI = name;
91
maxClassesToLoad = classesToLoad;
92
93
}
94
95
/**
96
* Just outputs given message preceeded with the thread identifier
97
*
98
* @param message text to print out
99
*/
100
void log(String message) {
101
System.out.println("%" + whoAmI + "% " + message);
102
}
103
104
void throwFault(String message) {
105
throw new TestFault("%" + whoAmI + "% " + message);
106
}
107
108
void throwFault(String message, Throwable t) {
109
throw new TestFault("%" + whoAmI + "% " + message, t);
110
}
111
112
/**
113
* Entry to the test.
114
* Just exits if passes or throws an Error if failed.
115
*/
116
public void run() {
117
if (System.getProperty("requiresCompressedClassSpace") != null &&
118
!isCompressedClassSpaceAvailable()) {
119
System.out.println("Not applicalbe, Compressed Class Space is required");
120
return;
121
}
122
123
try {
124
log("Bootstrapping string concatenation for " + whoAmI );
125
go();
126
// The quest completed! Yahoo!
127
setErrorMessage(null);
128
log("passed");
129
} catch (TestFault failure) {
130
failure.printStackTrace(System.err);
131
setErrorMessage(failure.getMessage());
132
log("failed :" + errorMessage);
133
throw failure;
134
} catch (Throwable badThing) {
135
setErrorMessage(badThing.toString());
136
throw new TestFault(badThing);
137
}
138
}
139
140
private void go() {
141
// step 1: eat all metaspace
142
log("eating metaspace");
143
runOutOfMetaspace(maxClassesToLoad);
144
145
// step 2: try to load one more class
146
// it should be impossible
147
try {
148
eatALittleMemory();
149
throwFault("We haven't cleaned metaspace yet!");
150
} catch (OutOfMemoryError error) {
151
if (!isMetaspaceError(error)) {
152
throwFault("Hmm, we ran out metaspace. Metaspace error is still excpected here " + error, error);
153
}
154
}
155
156
// step 3: clean up metaspace and try loading a class again.
157
log("washing hands before meal");
158
loadedClasses.clear();
159
System.gc();
160
try {
161
log("one more try to eat");
162
eatALittleMemory();
163
} catch (OutOfMemoryError error) {
164
throwFault("we already should be able to consume metaspace " + error, error);
165
}
166
}
167
168
/**
169
* @return true if the test has successfully passed.
170
*/
171
public boolean isPassed() {
172
return errorMessage == null;
173
}
174
175
/**
176
* @return message describing the reason of failure, or null if passes
177
*/
178
public String getErrorMessage() {
179
return errorMessage;
180
}
181
182
/**
183
* Sets the message describing why test failed, or null if test passed
184
*/
185
void setErrorMessage(String msg) {
186
errorMessage = msg;
187
}
188
189
/**
190
* Loads new classes until OOM.
191
* Checks that OOM is caused by metaspace and throws an Error if not.
192
*
193
* @param times - maximum limit of classes to load.
194
*/
195
private void runOutOfMetaspace(int times) {
196
try {
197
for (int i = 0; i < times; i++) {
198
eatALittleMemory();
199
}
200
} catch (OutOfMemoryError error) {
201
if (isMetaspaceError(error)) {
202
return;
203
}
204
throwFault("We ran out of another space, not metaspace: " + error, error);
205
}
206
throwFault("OOM hasn't happened after " + times + " iterations. Might be too much space?..");
207
}
208
209
/**
210
* Imitates class loading.
211
* Each invocation of this method causes a new class loader object is created
212
* and a new class is loaded by this class loader.
213
* Method throws OOM when run out of memory.
214
*/
215
private void eatALittleMemory() {
216
try {
217
String jarUrl = "file:" + counter + ".jar";
218
counter++;
219
URL[] urls = new URL[]{new URL(jarUrl)};
220
URLClassLoader cl = new URLClassLoader(urls);
221
ShrinkGrowTest.Foo foo = (ShrinkGrowTest.Foo) Proxy.newProxyInstance(cl,
222
new Class[]{ShrinkGrowTest.Foo.class},
223
new ShrinkGrowTest.FooInvocationHandler(new ShrinkGrowTest.FooBar()));
224
loadedClasses.put(jarUrl, foo);
225
} catch (java.net.MalformedURLException badThing) {
226
// should never occur
227
throwFault("Unexpeted error: " + badThing, badThing);
228
}
229
230
}
231
232
/**
233
* Checks if given OOM is about metaspace
234
* @param error OOM
235
* @return true if message contains 'metaspace' word, false otherwise.
236
*/
237
boolean isMetaspaceError(OutOfMemoryError error) {
238
String message = error.getMessage();
239
return message != null && (message.contains("Metaspace") ||
240
message.contains("Compressed class space"));
241
}
242
243
boolean isCompressedClassSpaceAvailable() {
244
for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {
245
if (pool.getName().equalsIgnoreCase("Compressed class space")) {
246
return true;
247
}
248
}
249
return false;
250
}
251
252
/**
253
* Runtime exception signaling test failure.
254
*/
255
public static class TestFault extends RuntimeException {
256
public TestFault(String message) {
257
super(message);
258
}
259
public TestFault(Throwable t) {
260
super(t);
261
}
262
public TestFault(String message, Throwable t) {
263
super(message, t);
264
}
265
}
266
267
public static interface Foo {
268
}
269
270
public static class FooBar implements ShrinkGrowTest.Foo {
271
}
272
273
class FooInvocationHandler implements InvocationHandler {
274
private final ShrinkGrowTest.Foo foo;
275
276
FooInvocationHandler(ShrinkGrowTest.Foo foo) {
277
this.foo = foo;
278
}
279
280
@Override
281
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
282
return method.invoke(foo, args);
283
}
284
}
285
}
286
287