Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/gc/logging/TestUnifiedLoggingSwitchStress.java
40942 views
1
/*
2
* Copyright (c) 2016, 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
package gc.logging;
25
26
import jdk.test.lib.Utils;
27
28
import javax.management.InstanceNotFoundException;
29
import javax.management.MBeanException;
30
import javax.management.MBeanServer;
31
import javax.management.MalformedObjectNameException;
32
import javax.management.ObjectName;
33
import javax.management.ReflectionException;
34
35
import static gc.testlibrary.Allocation.blackHole;
36
37
import java.lang.management.ManagementFactory;
38
import java.util.LinkedList;
39
import java.util.List;
40
import java.util.Random;
41
42
43
/**
44
* @test TestUnifiedLoggingSwitchStress
45
* @key stress randomness
46
* @summary Switches gc log level on fly while stressing memory/gc
47
* @requires !vm.flightRecorder
48
* @requires vm.gc != "Z"
49
* @library /test/lib /
50
* @modules java.management java.base/jdk.internal.misc
51
*
52
* @run main/othervm -Xmx256M -Xms256M
53
* gc.logging.TestUnifiedLoggingSwitchStress 60
54
*/
55
56
class MemoryStresser implements Runnable {
57
public static volatile boolean shouldStop = false;
58
59
private final List<byte[]> liveObjects = new LinkedList<>();
60
private final List<byte[]> liveHObjects = new LinkedList<>();
61
private int maxSimpleAllocationMemory = 0;
62
private int usedMemory = 0;
63
64
/**
65
* Maximum amount of huge allocations
66
*/
67
private static int H_ALLOCATION_MAX_COUNT = 4;
68
/**
69
* Maximum regions in one huge allocation
70
*/
71
private static int H_ALLOCATION_REGION_SIZE = 2;
72
private static final int G1_REGION_SIZE = 1024 * 1024;
73
/**
74
* Maximum size of simple allocation
75
*/
76
private static final int MAX_SIMPLE_ALLOCATION_SIZE = (int) (G1_REGION_SIZE / 2 * 0.9);
77
78
/**
79
* Maximum size of dead (i.e. one which is made unreachable right after allocation) object
80
*/
81
private static final int DEAD_OBJECT_MAX_SIZE = G1_REGION_SIZE / 10;
82
private final Random rnd = new Random(Utils.getRandomInstance().nextLong());
83
84
/**
85
* @param maxMemory maximum memory that could be allocated
86
*/
87
public MemoryStresser(int maxMemory) {
88
maxSimpleAllocationMemory = maxMemory - G1_REGION_SIZE * H_ALLOCATION_MAX_COUNT * H_ALLOCATION_REGION_SIZE;
89
}
90
91
public final Runnable[] actions = new Runnable[]{
92
// Huge allocation
93
() -> {
94
if (liveHObjects.size() < H_ALLOCATION_MAX_COUNT) {
95
int allocationSize = rnd.nextInt((int) (G1_REGION_SIZE * (H_ALLOCATION_REGION_SIZE - 0.5)
96
* 0.9));
97
liveHObjects.add(new byte[allocationSize + G1_REGION_SIZE / 2]);
98
}
99
},
100
101
// Huge deallocation
102
() -> {
103
if (liveHObjects.size() > 0) {
104
int elementNum = rnd.nextInt(liveHObjects.size());
105
liveHObjects.remove(elementNum);
106
}
107
},
108
109
// Simple allocation
110
() -> {
111
if (maxSimpleAllocationMemory - usedMemory != 0) {
112
int arraySize = rnd.nextInt(Math.min(maxSimpleAllocationMemory - usedMemory,
113
MAX_SIMPLE_ALLOCATION_SIZE));
114
if (arraySize != 0) {
115
liveObjects.add(new byte[arraySize]);
116
usedMemory += arraySize;
117
}
118
}
119
},
120
121
// Simple deallocation
122
() -> {
123
if (liveObjects.size() != 0) {
124
int elementNum = rnd.nextInt(liveObjects.size());
125
int shouldFree = liveObjects.get(elementNum).length;
126
liveObjects.remove(elementNum);
127
usedMemory -= shouldFree;
128
}
129
},
130
131
// Dead object allocation
132
() -> {
133
int size = rnd.nextInt(DEAD_OBJECT_MAX_SIZE);
134
blackHole(new byte[size]);
135
}
136
};
137
138
@Override
139
public void run() {
140
while (!shouldStop) {
141
actions[rnd.nextInt(actions.length)].run();
142
Thread.yield();
143
}
144
145
System.out.println("Memory Stresser finished");
146
}
147
}
148
149
class LogLevelSwitcher implements Runnable {
150
151
public static volatile boolean shouldStop = false;
152
private final int logCount; // how many various log files will be used
153
private final String logFilePrefix; // name of log file will be logFilePrefix + index
154
private final Random rnd;
155
private final MBeanServer MBS = ManagementFactory.getPlatformMBeanServer();
156
157
/**
158
* @param logFilePrefix prefix for log files
159
* @param logCount amount of log files
160
*/
161
public LogLevelSwitcher(String logFilePrefix, int logCount) {
162
this.logCount = logCount;
163
this.logFilePrefix = logFilePrefix;
164
this.rnd = new Random(Utils.getRandomInstance().nextLong());
165
}
166
167
private static final String[] LOG_LEVELS = {"error", "warning", "info", "debug", "trace"};
168
169
@Override
170
public void run() {
171
172
while (!shouldStop) {
173
int fileNum = rnd.nextInt(logCount);
174
int logLevel = rnd.nextInt(LOG_LEVELS.length);
175
176
String outputCommand = String.format("output=%s_%d.log", logFilePrefix, fileNum);
177
String logLevelCommand = "what='gc*=" + LOG_LEVELS[logLevel] + "'";
178
179
try {
180
Object out = MBS.invoke(new ObjectName("com.sun.management:type=DiagnosticCommand"),
181
"vmLog",
182
new Object[]{new String[]{outputCommand, logLevelCommand}},
183
new String[]{String[].class.getName()});
184
185
if (!out.toString().isEmpty()) {
186
System.out.format("WARNING: Diagnostic command vmLog with arguments %s,%s returned not empty"
187
+ " output %s\n",
188
outputCommand, logLevelCommand, out);
189
}
190
} catch (InstanceNotFoundException | MBeanException | ReflectionException | MalformedObjectNameException e) {
191
System.out.println("Got exception trying to change log level:" + e);
192
e.printStackTrace();
193
throw new Error(e);
194
}
195
Thread.yield();
196
}
197
System.out.println("Log Switcher finished");
198
}
199
}
200
201
202
public class TestUnifiedLoggingSwitchStress {
203
/**
204
* Count of memory stressing threads
205
*/
206
private static final int MEMORY_STRESSERS_COUNT = 3;
207
/**
208
* Count of log switching threads
209
*/
210
private static final int LOG_LEVEL_SWITCHERS_COUNT = 2;
211
/**
212
* Count of log files created by each log switching thread
213
*/
214
private static final int LOG_FILES_COUNT = 2;
215
/**
216
* Maximum amount memory allocated by each stressing thread
217
*/
218
private static final int MAX_MEMORY_PER_STRESSER = (int) (Runtime.getRuntime().freeMemory()
219
/ MEMORY_STRESSERS_COUNT * 0.7);
220
221
public static void main(String[] args) throws InterruptedException {
222
if (args.length != 1) {
223
throw new Error("Test Bug: Expected duration (in seconds) wasn't provided as command line argument");
224
}
225
long duration = Integer.parseInt(args[0]) * 1000;
226
227
long startTime = System.currentTimeMillis();
228
229
List<Thread> threads = new LinkedList<>();
230
231
for (int i = 0; i < LOG_LEVEL_SWITCHERS_COUNT; i++) {
232
threads.add(new Thread(new LogLevelSwitcher("Output_" + i, LOG_FILES_COUNT)));
233
}
234
235
for (int i = 0; i < MEMORY_STRESSERS_COUNT; i++) {
236
threads.add(new Thread(new MemoryStresser(MAX_MEMORY_PER_STRESSER)));
237
}
238
239
threads.stream().forEach(Thread::start);
240
241
while (System.currentTimeMillis() - startTime < duration) {
242
Thread.yield();
243
}
244
245
MemoryStresser.shouldStop = true;
246
LogLevelSwitcher.shouldStop = true;
247
}
248
}
249
250