Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest2.java
38821 views
1
/*
2
* Copyright (c) 2004, 2013, 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
* Test low memory detection of non-heap memory pool.
26
*
27
* The test set a listener to be notified when any of the non-heap pools
28
* exceed 80%. It then starts a thread that continuously loads classes.
29
* In the HotSpot implementation this causes metaspace to be consumed.
30
* Test completes when we the notification is received or an OutOfMemory
31
* is generated.
32
*/
33
34
import java.lang.management.*;
35
import javax.management.*;
36
import javax.management.openmbean.CompositeData;
37
import java.util.*;
38
39
public class LowMemoryTest2 {
40
41
private static volatile boolean listenerInvoked = false;
42
43
private static String INDENT = " ";
44
45
static class SensorListener implements NotificationListener {
46
public void handleNotification(Notification notif, Object handback) {
47
String type = notif.getType();
48
if (type.equals(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED) ||
49
type.equals(MemoryNotificationInfo.
50
MEMORY_COLLECTION_THRESHOLD_EXCEEDED)) {
51
listenerInvoked = true;
52
MemoryNotificationInfo minfo = MemoryNotificationInfo.
53
from((CompositeData) notif.getUserData());
54
55
System.out.print("Notification for " + minfo.getPoolName());
56
System.out.print(" [type = " + type);
57
System.out.println(" count = " + minfo.getCount() + "]");
58
System.out.println(INDENT + "usage = " + minfo.getUsage());
59
}
60
}
61
}
62
63
// Loads classes Test100001, Test100002, .... until OutOfMemoryErrror or
64
// low memory notification
65
66
static class BoundlessLoaderThread extends ClassLoader implements Runnable {
67
68
static int count = 100000;
69
70
Class loadNext() throws ClassNotFoundException {
71
72
// public class TestNNNNNN extends java.lang.Object{
73
// public TestNNNNNN();
74
// Code:
75
// 0: aload_0
76
// 1: invokespecial #1; //Method java/lang/Object."<init>":()V
77
// 4: return
78
// }
79
80
int begin[] = {
81
0xca, 0xfe, 0xba, 0xbe, 0x00, 0x00, 0x00, 0x30,
82
0x00, 0x0a, 0x0a, 0x00, 0x03, 0x00, 0x07, 0x07,
83
0x00, 0x08, 0x07, 0x00, 0x09, 0x01, 0x00, 0x06,
84
0x3c, 0x69, 0x6e, 0x69, 0x74, 0x3e, 0x01, 0x00,
85
0x03, 0x28, 0x29, 0x56, 0x01, 0x00, 0x04, 0x43,
86
0x6f, 0x64, 0x65, 0x0c, 0x00, 0x04, 0x00, 0x05,
87
0x01, 0x00, 0x0a, 0x54, 0x65, 0x73, 0x74 };
88
89
int end [] = {
90
0x01, 0x00, 0x10,
91
0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c, 0x61, 0x6e,
92
0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,
93
0x00, 0x21, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00,
94
0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04,
95
0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00,
96
0x00, 0x11, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
97
0x00, 0x05, 0x2a, 0xb7, 0x00, 0x01, 0xb1, 0x00,
98
0x00, 0x00, 0x00, 0x00, 0x00 };
99
100
101
// TestNNNNNN
102
103
int load_count = count++;
104
if (load_count > 999999) {
105
// The test will create a corrupt class file if the count
106
// exceeds 999999. Fix the test if this exception is thrown.
107
throw new RuntimeException("Load count exceeded");
108
}
109
110
String name = "Test" + Integer.toString(load_count);
111
112
byte value[];
113
try {
114
value = name.substring(4).getBytes("UTF-8");
115
} catch (java.io.UnsupportedEncodingException x) {
116
throw new Error();
117
}
118
119
// construct class file
120
121
int len = begin.length + value.length + end.length;
122
byte b[] = new byte[len];
123
int i, pos=0;
124
for (i=0; i<begin.length; i++) {
125
b[pos++] = (byte)begin[i];
126
}
127
for (i=0; i<value.length; i++) {
128
b[pos++] = value[i];
129
}
130
for (i=0; i<end.length; i++) {
131
b[pos++] = (byte)end[i];
132
}
133
134
return defineClass(name, b, 0, b.length);
135
}
136
137
/*
138
* Run method for thread that continuously loads classes.
139
*
140
* Note: Once the usage threshold has been exceeded the low memory
141
* detector thread will attempt to deliver its notification - this can
142
* potentially create a race condition with this thread contining to
143
* fill up metaspace. To avoid the low memory detector getting an
144
* OutOfMemory we throttle this thread once the threshold has been
145
* exceeded.
146
*/
147
public void run() {
148
List pools = ManagementFactory.getMemoryPoolMXBeans();
149
boolean thresholdExceeded = false;
150
151
for (;;) {
152
try {
153
// the classes are small so we load 10 at a time
154
for (int i=0; i<10; i++) {
155
loadNext();
156
}
157
} catch (ClassNotFoundException x) {
158
return;
159
}
160
if (listenerInvoked) {
161
return;
162
}
163
164
// if threshold has been exceeded we put in a delay to allow
165
// the low memory detector do its job.
166
if (thresholdExceeded) {
167
try {
168
Thread.currentThread().sleep(100);
169
} catch (InterruptedException x) { }
170
} else {
171
// check if the threshold has been exceeded
172
ListIterator i = pools.listIterator();
173
while (i.hasNext()) {
174
MemoryPoolMXBean p = (MemoryPoolMXBean) i.next();
175
if (p.getType() == MemoryType.NON_HEAP &&
176
p.isUsageThresholdSupported())
177
{
178
thresholdExceeded = p.isUsageThresholdExceeded();
179
}
180
}
181
}
182
}
183
}
184
}
185
186
public static void main(String args[]) {
187
ListIterator iter = ManagementFactory.getMemoryPoolMXBeans().listIterator();
188
189
// Set threshold of 80% of all NON_HEAP memory pools
190
// In the Hotspot implementation this means we should get a notification
191
// if the CodeCache or metaspace fills up.
192
193
while (iter.hasNext()) {
194
MemoryPoolMXBean p = (MemoryPoolMXBean) iter.next();
195
if (p.getType() == MemoryType.NON_HEAP && p.isUsageThresholdSupported()) {
196
197
// set threshold
198
MemoryUsage mu = p.getUsage();
199
long max = mu.getMax();
200
if (max < 0) {
201
throw new RuntimeException("There is no maximum set for "
202
+ p.getName() + " memory pool so the test is invalid");
203
}
204
long threshold = (max * 80) / 100;
205
206
p.setUsageThreshold(threshold);
207
208
System.out.println("Selected memory pool for low memory " +
209
"detection.");
210
MemoryUtil.printMemoryPool(p);
211
212
}
213
}
214
215
216
// Install the listener
217
218
MemoryMXBean mm = ManagementFactory.getMemoryMXBean();
219
SensorListener l2 = new SensorListener();
220
221
NotificationEmitter emitter = (NotificationEmitter) mm;
222
emitter.addNotificationListener(l2, null, null);
223
224
// Start the thread loading classes
225
226
Thread thr = new Thread(new BoundlessLoaderThread());
227
thr.start();
228
229
// Wait for the thread to terminate
230
try {
231
thr.join();
232
} catch (InterruptedException x) {
233
throw new RuntimeException(x);
234
}
235
236
if (listenerInvoked) {
237
System.out.println("Notification received - test passed.");
238
} else {
239
throw new RuntimeException("Test failed - notification not received!");
240
}
241
}
242
243
}
244
245