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/mixedgc/TestOldGenCollectionUsage.java
32285 views
1
/*
2
* Copyright (c) 2018, 2019, 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 TestOldGenCollectionUsage.java
26
* @bug 8195115
27
* @summary G1 Old Gen's CollectionUsage.used is zero after mixed GC which is incorrect
28
* @key gc
29
* @requires vm.gc=="G1" | vm.gc=="null"
30
* @library /testlibrary /testlibrary/whitebox
31
* @build ClassFileInstaller com.oracle.java.testlibrary.* sun.hotspot.WhiteBox TestOldGenCollectionUsage
32
* @run main ClassFileInstaller sun.hotspot.WhiteBox
33
* sun.hotspot.WhiteBox$WhiteBoxPermission
34
* @run main/othervm -Xbootclasspath/a:. -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
35
* -XX:+WhiteBoxAPI -verbose:gc -XX:SurvivorRatio=1 -Xmx14m -Xms14m -XX:MaxTenuringThreshold=1
36
* -XX:InitiatingHeapOccupancyPercent=100 -XX:G1MixedGCCountTarget=4 -XX:MaxGCPauseMillis=30000
37
* -XX:G1HeapRegionSize=1m -XX:G1HeapWastePercent=0 -XX:G1MixedGCLiveThresholdPercent=100
38
* TestOldGenCollectionUsage
39
*/
40
41
import com.oracle.java.testlibrary.Asserts;
42
import sun.hotspot.WhiteBox;
43
44
import java.util.ArrayList;
45
import java.util.List;
46
import java.util.Collections;
47
48
import java.lang.management.*;
49
50
// 8195115 says that for the "G1 Old Gen" MemoryPool, CollectionUsage.used
51
// is zero for G1 after a mixed collection, which is incorrect.
52
53
public class TestOldGenCollectionUsage {
54
55
private String poolName = "G1 Old Gen";
56
private String collectorName = "G1 Young Generation";
57
58
public static void main(String [] args) throws Exception {
59
TestOldGenCollectionUsage t = new TestOldGenCollectionUsage();
60
t.run();
61
}
62
63
public TestOldGenCollectionUsage() {
64
System.out.println("Monitor G1 Old Gen pool with G1 Young Generation collector.");
65
}
66
67
public void run() {
68
// Find memory pool and collector
69
List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
70
MemoryPoolMXBean pool = null;
71
boolean foundPool = false;
72
for (int i = 0; i < pools.size(); i++) {
73
pool = pools.get(i);
74
String name = pool.getName();
75
if (name.contains(poolName)) {
76
System.out.println("Found pool: " + name);
77
foundPool = true;
78
break;
79
}
80
}
81
if (!foundPool) {
82
throw new RuntimeException(poolName + " not found, test with -XX:+UseG1GC");
83
}
84
85
List<GarbageCollectorMXBean> collectors = ManagementFactory.getGarbageCollectorMXBeans();
86
GarbageCollectorMXBean collector = null;
87
boolean foundCollector = false;
88
for (int i = 0; i < collectors.size(); i++) {
89
collector = collectors.get(i);
90
String name = collector.getName();
91
if (name.contains(collectorName)) {
92
System.out.println("Found collector: " + name);
93
foundCollector = true;
94
break;
95
}
96
}
97
if (!foundCollector) {
98
throw new RuntimeException(collectorName + " not found, test with -XX:+UseG1GC");
99
}
100
101
MixedGCProvoker gcProvoker = new MixedGCProvoker();
102
gcProvoker.allocateOldObjects();
103
104
// Verify no non-zero result was stored
105
long usage = pool.getCollectionUsage().getUsed();
106
System.out.println(poolName + ": usage after GC = " + usage);
107
if (usage > 0) {
108
throw new RuntimeException("Premature mixed collections(s)");
109
}
110
111
// Verify that collections were done
112
long collectionCount = collector.getCollectionCount();
113
System.out.println(collectorName + ": collection count = "
114
+ collectionCount);
115
long collectionTime = collector.getCollectionTime();
116
System.out.println(collectorName + ": collection time = "
117
+ collectionTime);
118
if (collectionCount <= 0) {
119
throw new RuntimeException("Collection count <= 0");
120
}
121
if (collectionTime <= 0) {
122
throw new RuntimeException("Collector has not run");
123
}
124
125
gcProvoker.provokeMixedGC();
126
127
usage = pool.getCollectionUsage().getUsed();
128
System.out.println(poolName + ": usage after GC = " + usage);
129
if (usage <= 0) {
130
throw new RuntimeException(poolName + " found with zero usage");
131
}
132
133
long newCollectionCount = collector.getCollectionCount();
134
System.out.println(collectorName + ": collection count = "
135
+ newCollectionCount);
136
long newCollectionTime = collector.getCollectionTime();
137
System.out.println(collectorName + ": collection time = "
138
+ newCollectionTime);
139
if (newCollectionCount <= collectionCount) {
140
throw new RuntimeException("No new collection");
141
}
142
if (newCollectionTime <= collectionTime) {
143
throw new RuntimeException("Collector has not run some more");
144
}
145
146
System.out.println("Test passed.");
147
}
148
149
/**
150
* Utility class to guarantee a mixed GC. The class allocates several arrays and
151
* promotes them to the oldgen. After that it tries to provoke mixed GC by
152
* allocating new objects.
153
*
154
* The necessary condition for guaranteed mixed GC is running MixedGCProvoker is
155
* running in VM with the following flags: -XX:MaxTenuringThreshold=1 -Xms12M
156
* -Xmx12M -XX:G1MixedGCLiveThresholdPercent=100 -XX:G1HeapWastePercent=0
157
* -XX:G1HeapRegionSize=1m
158
*/
159
public class MixedGCProvoker {
160
private final WhiteBox WB = WhiteBox.getWhiteBox();
161
private final List<byte[]> liveOldObjects = new ArrayList<>();
162
private final List<byte[]> newObjects = new ArrayList<>();
163
164
public static final int ALLOCATION_SIZE = 20000;
165
public static final int ALLOCATION_COUNT = 15;
166
167
public void allocateOldObjects() {
168
List<byte[]> deadOldObjects = new ArrayList<>();
169
// Allocates buffer and promotes it to the old gen. Mix live and dead old
170
// objects
171
for (int i = 0; i < ALLOCATION_COUNT; ++i) {
172
liveOldObjects.add(new byte[ALLOCATION_SIZE * 5]);
173
deadOldObjects.add(new byte[ALLOCATION_SIZE * 5]);
174
}
175
176
// Do two young collections, MaxTenuringThreshold=1 will force promotion.
177
// G1HeapRegionSize=1m guarantees that old gen regions will be filled.
178
WB.youngGC();
179
WB.youngGC();
180
// Check it is promoted & keep alive
181
Asserts.assertTrue(WB.isObjectInOldGen(liveOldObjects),
182
"List of the objects is suppose to be in OldGen");
183
Asserts.assertTrue(WB.isObjectInOldGen(deadOldObjects),
184
"List of the objects is suppose to be in OldGen");
185
}
186
187
/**
188
* Waits until Concurent Mark Cycle finishes
189
* @param wb Whitebox instance
190
* @param sleepTime sleep time
191
*/
192
private void waitTillCMCFinished(int sleepTime) {
193
while (WB.g1InConcurrentMark()) {
194
if (sleepTime > -1) {
195
try {
196
Thread.sleep(sleepTime);
197
} catch (InterruptedException e) {
198
System.out.println("Got InterruptedException while waiting for ConcMarkCycle to finish");
199
}
200
}
201
}
202
}
203
204
public void provokeMixedGC() {
205
waitTillCMCFinished(0);
206
WB.g1StartConcMarkCycle();
207
waitTillCMCFinished(0);
208
WB.youngGC();
209
210
System.out.println("Allocating new objects to provoke mixed GC");
211
// Provoke a mixed collection. G1MixedGCLiveThresholdPercent=100
212
// guarantees that full old gen regions will be included.
213
for (int i = 0; i < (ALLOCATION_COUNT * 20); i++) {
214
try {
215
newObjects.add(new byte[ALLOCATION_SIZE]);
216
} catch (OutOfMemoryError e) {
217
newObjects.clear();
218
WB.youngGC();
219
WB.youngGC();
220
System.out.println("OutOfMemoryError is reported, stop allocating new objects");
221
break;
222
}
223
}
224
// check that liveOldObjects still alive
225
Asserts.assertTrue(WB.isObjectInOldGen(liveOldObjects),
226
"List of the objects is suppose to be in OldGen");
227
}
228
229
}
230
231
}
232
233