mirror of
https://github.com/openjdk/jdk.git
synced 2026-06-10 12:37:09 +00:00
8208250: Rewrite metaspace firstGC tests to use JFR instead of GC log parsing
This commit is contained in:
parent
e155a20b49
commit
239c9bbbed
@ -164,11 +164,6 @@ serviceability/jvmti/stress/StackTrace/NotSuspended/GetStackTraceNotSuspendedStr
|
||||
vmTestbase/gc/gctests/FinalizeTest04/FinalizeTest04.java 8284234 generic-all
|
||||
vmTestbase/gc/gctests/PhantomReference/phantom001/phantom001.java 8284234 generic-all
|
||||
|
||||
vmTestbase/metaspace/gc/firstGC_10m/TestDescription.java 8208250 generic-all
|
||||
vmTestbase/metaspace/gc/firstGC_50m/TestDescription.java 8208250 generic-all
|
||||
vmTestbase/metaspace/gc/firstGC_99m/TestDescription.java 8208250 generic-all
|
||||
vmTestbase/metaspace/gc/firstGC_default/TestDescription.java 8208250 generic-all
|
||||
|
||||
vmTestbase/nsk/jvmti/scenarios/capability/CM03/cm03t001/TestDescription.java 8073470 linux-all
|
||||
vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t006/TestDescription.java 8372206 generic-all
|
||||
vmTestbase/nsk/jvmti/InterruptThread/intrpthrd003/TestDescription.java 8288911 macosx-all
|
||||
|
||||
183
test/hotspot/jtreg/gc/metaspace/TestMetaspaceFirstGC.java
Normal file
183
test/hotspot/jtreg/gc/metaspace/TestMetaspaceFirstGC.java
Normal file
@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test TestMetaspaceFirstGC
|
||||
* @bug 8208250
|
||||
* @summary Verify that the first metaspace GC happens near the MetaspaceSize threshold
|
||||
* @requires vm.hasJFR
|
||||
* @library /test/lib
|
||||
* @run main/othervm -Xms200m -XX:-UseCompressedOops TestMetaspaceFirstGC
|
||||
* @run main/othervm -Xms200m -XX:-UseCompressedOops -XX:MetaspaceSize=10m TestMetaspaceFirstGC 10m
|
||||
* @run main/othervm -Xms200m -XX:-UseCompressedOops -XX:MetaspaceSize=50m TestMetaspaceFirstGC 50m
|
||||
* @run main/othervm -Xms200m -XX:-UseCompressedOops -XX:MetaspaceSize=99m TestMetaspaceFirstGC 99m
|
||||
*/
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
import jdk.jfr.Recording;
|
||||
import jdk.jfr.consumer.RecordedEvent;
|
||||
import jdk.test.lib.Asserts;
|
||||
import jdk.test.lib.jfr.EventNames;
|
||||
import jdk.test.lib.jfr.Events;
|
||||
|
||||
public class TestMetaspaceFirstGC {
|
||||
|
||||
private static int classCounter = 0;
|
||||
|
||||
public interface Dummy {}
|
||||
|
||||
static class DummyHandler implements InvocationHandler {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
long expectedSize = -1;
|
||||
if (args.length > 0) {
|
||||
expectedSize = parseSize(args[0]);
|
||||
}
|
||||
|
||||
try (Recording recording = new Recording()) {
|
||||
recording.enable(EventNames.GarbageCollection);
|
||||
recording.enable(EventNames.MetaspaceSummary).withThreshold(Duration.ofMillis(0));
|
||||
recording.start();
|
||||
|
||||
// Load classes until a metaspace-triggered GC happens
|
||||
loadClassesUntilGC(50000);
|
||||
|
||||
recording.stop();
|
||||
|
||||
List<RecordedEvent> events = Events.fromRecording(recording);
|
||||
|
||||
// Find first GarbageCollection with cause "Metadata GC Threshold"
|
||||
RecordedEvent gcEvent = null;
|
||||
for (RecordedEvent event : events) {
|
||||
if (event.getEventType().getName().equals(EventNames.GarbageCollection)) {
|
||||
String cause = event.getString("cause");
|
||||
if ("Metadata GC Threshold".equals(cause)) {
|
||||
gcEvent = event;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gcEvent == null) {
|
||||
throw new RuntimeException("No GC with cause 'Metadata GC Threshold' found");
|
||||
}
|
||||
|
||||
int gcId = gcEvent.getInt("gcId");
|
||||
System.out.println("Found Metadata GC Threshold GC, gcId=" + gcId);
|
||||
|
||||
// Find matching MetaspaceSummary with same gcId and when="Before GC"
|
||||
RecordedEvent msEvent = null;
|
||||
for (RecordedEvent event : events) {
|
||||
if (event.getEventType().getName().equals(EventNames.MetaspaceSummary)) {
|
||||
if (event.getInt("gcId") == gcId && "Before GC".equals(event.getString("when"))) {
|
||||
msEvent = event;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (msEvent == null) {
|
||||
throw new RuntimeException("No MetaspaceSummary 'Before GC' found for gcId=" + gcId);
|
||||
}
|
||||
|
||||
long committed = msEvent.getLong("metaspace.committed");
|
||||
long gcThreshold = msEvent.getLong("gcThreshold");
|
||||
System.out.println("MetaspaceSummary: committed=" + committed + " gcThreshold=" + gcThreshold);
|
||||
|
||||
// committed should be reasonably close to gcThreshold
|
||||
long tolerance = 5 * 1024 * 1024; // 5MB tolerance
|
||||
Asserts.assertLessThanOrEqual(Math.abs(committed - gcThreshold), tolerance,
|
||||
"committed (" + committed + ") should be close to gcThreshold (" + gcThreshold + ")");
|
||||
|
||||
// If explicit MetaspaceSize given, gcThreshold should match it
|
||||
if (expectedSize > 0) {
|
||||
Asserts.assertLessThanOrEqual(Math.abs(gcThreshold - expectedSize), tolerance,
|
||||
"gcThreshold (" + gcThreshold + ") should be close to MetaspaceSize (" + expectedSize + ")");
|
||||
System.out.println("gcThreshold matches expected MetaspaceSize=" + expectedSize);
|
||||
}
|
||||
|
||||
System.out.println("PASSED");
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadClassesUntilGC(int maxIterations) {
|
||||
long prevUsed = getMetaspaceUsed();
|
||||
for (int i = 0; i < maxIterations; i++) {
|
||||
loadOneClass();
|
||||
long used = getMetaspaceUsed();
|
||||
if (used < prevUsed) {
|
||||
System.out.println("GC detected at iteration " + i +
|
||||
", used dropped from " + prevUsed + " to " + used);
|
||||
return;
|
||||
}
|
||||
prevUsed = used;
|
||||
}
|
||||
throw new RuntimeException("No metaspace GC after " + maxIterations + " class loads");
|
||||
}
|
||||
|
||||
private static void loadOneClass() {
|
||||
try {
|
||||
String jarUrl = "file:" + (classCounter++) + ".jar";
|
||||
URLClassLoader cl = new URLClassLoader(new URL[]{new URL(jarUrl)});
|
||||
Proxy.newProxyInstance(cl, new Class[]{Dummy.class}, new DummyHandler());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static long getMetaspaceUsed() {
|
||||
return java.lang.management.ManagementFactory.getMemoryPoolMXBeans().stream()
|
||||
.filter(p -> p.getName().equals("Metaspace"))
|
||||
.mapToLong(p -> p.getUsage().getUsed())
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new RuntimeException("Metaspace pool not found"));
|
||||
}
|
||||
|
||||
private static long parseSize(String size) {
|
||||
size = size.toLowerCase();
|
||||
long multiplier = 1;
|
||||
if (size.endsWith("m")) {
|
||||
multiplier = 1024 * 1024;
|
||||
size = size.substring(0, size.length() - 1);
|
||||
} else if (size.endsWith("k")) {
|
||||
multiplier = 1024;
|
||||
size = size.substring(0, size.length() - 1);
|
||||
} else if (size.endsWith("g")) {
|
||||
multiplier = 1024 * 1024 * 1024;
|
||||
size = size.substring(0, size.length() - 1);
|
||||
}
|
||||
return Long.parseLong(size) * multiplier;
|
||||
}
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
exclusiveAccess.dirs=.
|
||||
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.misc:+open
|
||||
*
|
||||
* @summary converted from VM Testbase metaspace/gc/firstGC_10m.
|
||||
* VM Testbase keywords: [nonconcurrent, quarantine]
|
||||
* VM Testbase comments: 8208250
|
||||
*
|
||||
* @library /vmTestbase /test/lib
|
||||
* @run main/othervm
|
||||
* -Xms200m
|
||||
* -Xlog:gc+heap=trace,gc:gc.log
|
||||
* -XX:MetaspaceSize=10m
|
||||
* -XX:+IgnoreUnrecognizedVMOptions
|
||||
* -XX:+UnlockDiagnosticVMOptions
|
||||
* -XX:-VerifyBeforeExit
|
||||
* -XX:-UseCompressedOops
|
||||
* metaspace.gc.FirstGCTest
|
||||
*/
|
||||
|
||||
@ -1 +0,0 @@
|
||||
exclusiveAccess.dirs=.
|
||||
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.misc:+open
|
||||
*
|
||||
* @summary converted from VM Testbase metaspace/gc/firstGC_50m.
|
||||
* VM Testbase keywords: [nonconcurrent, quarantine]
|
||||
* VM Testbase comments: 8208250
|
||||
*
|
||||
* @library /vmTestbase /test/lib
|
||||
* @run main/othervm
|
||||
* -Xms200m
|
||||
* -Xlog:gc+heap=trace,gc:gc.log
|
||||
* -XX:MetaspaceSize=50m
|
||||
* -XX:+IgnoreUnrecognizedVMOptions
|
||||
* -XX:+UnlockDiagnosticVMOptions
|
||||
* -XX:-VerifyBeforeExit
|
||||
* -XX:-UseCompressedOops
|
||||
* metaspace.gc.FirstGCTest
|
||||
*/
|
||||
|
||||
@ -1 +0,0 @@
|
||||
exclusiveAccess.dirs=.
|
||||
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.misc:+open
|
||||
*
|
||||
* @summary converted from VM Testbase metaspace/gc/firstGC_99m.
|
||||
* VM Testbase keywords: [nonconcurrent, quarantine]
|
||||
* VM Testbase comments: 8208250
|
||||
*
|
||||
* @library /vmTestbase /test/lib
|
||||
* @run main/othervm
|
||||
* -Xms200m
|
||||
* -Xlog:gc+heap=trace,gc:gc.log
|
||||
* -XX:MetaspaceSize=99m
|
||||
* -XX:+IgnoreUnrecognizedVMOptions
|
||||
* -XX:+UnlockDiagnosticVMOptions
|
||||
* -XX:-VerifyBeforeExit
|
||||
* -XX:-UseCompressedOops
|
||||
* metaspace.gc.FirstGCTest
|
||||
*/
|
||||
|
||||
@ -1 +0,0 @@
|
||||
exclusiveAccess.dirs=.
|
||||
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.base/jdk.internal.misc:+open
|
||||
*
|
||||
* @summary converted from VM Testbase metaspace/gc/firstGC_default.
|
||||
* VM Testbase keywords: [nonconcurrent, quarantine]
|
||||
* VM Testbase comments: 8208250
|
||||
*
|
||||
* @library /vmTestbase /test/lib
|
||||
* @run main/othervm
|
||||
* -Xms200m
|
||||
* -Xlog:gc+heap=trace,gc:gc.log
|
||||
* -XX:+IgnoreUnrecognizedVMOptions
|
||||
* -XX:+UnlockDiagnosticVMOptions
|
||||
* -XX:-VerifyBeforeExit
|
||||
* -XX:-UseCompressedOops
|
||||
* metaspace.gc.FirstGCTest
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user