Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/gc/g1/TestGreyReclaimedHumongousObjects.java
40942 views
1
/*
2
* Copyright (c) 2015, 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.g1;
25
26
/*
27
* @test TestGreyReclaimedHumongousObjects.java
28
* @bug 8069367 8185278
29
* @requires vm.gc.G1
30
* @summary Test handling of marked but unscanned reclaimed humongous objects.
31
* @modules jdk.management
32
* @run main/othervm -XX:+UseG1GC -Xss32m -Xmx128m -XX:G1HeapRegionSize=1m
33
* -XX:+UnlockExperimentalVMOptions
34
* -XX:+G1EagerReclaimHumongousObjects
35
* -XX:+G1EagerReclaimHumongousObjectsWithStaleRefs
36
* gc.g1.TestGreyReclaimedHumongousObjects 1048576 90
37
*/
38
39
// This test spawns a bunch of threads, each of them rapidly
40
// allocating large objects and storing them into a circular buffer
41
// associated with the thread. The circular buffer results in these
42
// objects becoming dead in fairly short order.
43
//
44
// The situation we're trying to provoke is
45
//
46
// (1) A humongous object H is marked and added to the mark stack.
47
//
48
// (2) An evacuation pause determines H is no longer live, and
49
// reclaims it. This occurs before concurrent marking has gotten
50
// around to processing the mark stack entry for H.
51
//
52
// (3) Concurrent marking processes the mark stack entry for H. The
53
// bug is that it would attempt to scan the now dead object.
54
//
55
// Unfortunately, this test is *very* sensitive to configuration.
56
// Among the parameters that affect whether / how often we'll get into
57
// the desired situation within a reasonable amount of time are:
58
//
59
// - THREAD_COUNT: The number of allocating threads.
60
//
61
// - OLD_COUNT: The number of objects each thread keeps.
62
//
63
// - MAX_MEMORY: The maximum heap size.
64
//
65
// - G1HeapRegionSize
66
//
67
// - The size of the objects being allocated.
68
//
69
// The parameter values specified here:
70
//
71
// - THREAD_COUNT = 12
72
// - OLD_COUNT == 4
73
// - MAX_MEMORY == 128m
74
// - G1HeapRegionSize = 1m
75
// - Object size = 1048576 (2 regions after header overhead and roundup)
76
//
77
// seems to work well at provoking the desired state fairly quickly.
78
// Even relatively small perturbations may change that. The key
79
// factors seem to be keeping the heap mostly full of live objects but
80
// having them become dead fairly quickly.
81
82
import java.util.Date;
83
import java.util.concurrent.ExecutorService;
84
import java.util.concurrent.Executors;
85
import java.util.concurrent.ThreadFactory;
86
import java.util.concurrent.TimeUnit;
87
import com.sun.management.HotSpotDiagnosticMXBean;
88
import java.lang.management.ManagementFactory;
89
90
public class TestGreyReclaimedHumongousObjects {
91
92
static class NamedThreadFactory implements ThreadFactory {
93
private int threadNum = 0;
94
95
@Override
96
public Thread newThread(Runnable r) {
97
return new Thread(r, THREAD_NAME + (threadNum++));
98
}
99
}
100
101
static class Runner extends Thread {
102
private final Date startDate = new Date();
103
private final int obj_size;
104
private final Object[] old_garbage;
105
private int old_index = 0;
106
107
public Runner(int obj_size) {
108
this.obj_size = obj_size;
109
old_garbage = new Object[OLD_COUNT];
110
}
111
112
private void allocate_garbage() {
113
byte[] garbage = new byte[obj_size];
114
old_garbage[Math.abs(++old_index % OLD_COUNT)] = garbage;
115
}
116
117
@Override
118
public void run() {
119
try {
120
while (!isInterrupted()) {
121
allocate_garbage();
122
Thread.sleep(0); // Yield, to ensure interruptable.
123
}
124
} catch (InterruptedException e) {
125
System.out.println("Aborted after "
126
+ (new Date().getTime() - startDate.getTime())
127
+ " ms");
128
interrupt();
129
}
130
}
131
}
132
133
public static void main(String[] args) throws Exception {
134
HotSpotDiagnosticMXBean diagnostic =
135
ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
136
137
System.out.println("Max memory= " + MAX_MEMORY + " bytes");
138
139
int obj_size = 0;
140
long seconds_to_run = 0;
141
if (args.length != 2) {
142
throw new RuntimeException("Object size argument must be supplied");
143
} else {
144
obj_size = Integer.parseInt(args[0]);
145
seconds_to_run = Integer.parseInt(args[1]);
146
}
147
System.out.println("Objects size= " + obj_size + " bytes");
148
System.out.println("Seconds to run=" + seconds_to_run);
149
150
int region_size =
151
Integer.parseInt(diagnostic.getVMOption("G1HeapRegionSize").getValue());
152
if (obj_size < (region_size / 2)) {
153
throw new RuntimeException("Object size " + obj_size +
154
" is not humongous with region size " + region_size);
155
}
156
157
ExecutorService executor =
158
Executors.newFixedThreadPool(THREAD_COUNT, new NamedThreadFactory());
159
System.out.println("Starting " + THREAD_COUNT + " threads");
160
161
for (int i = 0; i < THREAD_COUNT; i++) {
162
executor.execute(new Runner(obj_size));
163
}
164
165
Thread.sleep(seconds_to_run * 1000);
166
executor.shutdownNow();
167
168
if (!executor.awaitTermination(10, TimeUnit.SECONDS)) {
169
System.err.println("Thread pool did not terminate after 10 seconds after shutdown");
170
}
171
}
172
173
private static final long MAX_MEMORY = Runtime.getRuntime().maxMemory();
174
private static final int OLD_COUNT = 4;
175
private static final int THREAD_COUNT = 12;
176
private static final String THREAD_NAME = "TestGreyRH-";
177
}
178
179