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