8261483: jdk/dynalink/TypeConverterFactoryMemoryLeakTest.java failed with "AssertionError: Should have GCd a method handle by now"

Reviewed-by: shade, plevart
This commit is contained in:
Attila Szegedi 2021-03-02 12:25:25 +00:00
parent 85a5ae8cb7
commit d185a6c53e
3 changed files with 84 additions and 23 deletions

@ -817,8 +817,6 @@ javax/rmi/ssl/SSLSocketParametersTest.sh 8162906 generic-
javax/script/Test7.java 8239361 generic-all
jdk/dynalink/TypeConverterFactoryMemoryLeakTest.java 8261483 generic-all
############################################################################
# jdk_jfr

@ -22,10 +22,43 @@
*/
/*
* @test
* @test id=with_SerialGC
* @requires vm.gc.Serial
* @bug 8198540
* @summary Test TypeConverterFactory is not leaking method handles
* @author Attila Szegedi
* @summary Test TypeConverterFactory is not leaking method handles (Serial GC)
* @run main/othervm -XX:+UseSerialGC TypeConverterFactoryMemoryLeakTest
*/
/*
* @test id=with_ParallelGC
* @requires vm.gc.Parallel
* @bug 8198540
* @summary Test TypeConverterFactory is not leaking method handles (Parallel GC)
* @run main/othervm -XX:+UseParallelGC TypeConverterFactoryMemoryLeakTest
*/
/*
* @test id=with_G1GC
* @requires vm.gc.G1
* @bug 8198540
* @summary Test TypeConverterFactory is not leaking method handles (G1 GC)
* @run main/othervm -XX:+UseG1GC TypeConverterFactoryMemoryLeakTest
*/
/*
* @test id=with_ZGC
* @requires vm.gc.Z
* @bug 8198540
* @summary Test TypeConverterFactory is not leaking method handles (Z GC)
* @run main/othervm -XX:+UseZGC TypeConverterFactoryMemoryLeakTest
*/
/*
* @test id=with_ShenandoahGC
* @requires vm.gc.Shenandoah
* @bug 8198540
* @summary Test TypeConverterFactory is not leaking method handles (Shenandoah GC)
* @run main/othervm -XX:+UseShenandoahGC TypeConverterFactoryMemoryLeakTest
*/
import java.lang.invoke.MethodHandles;
@ -34,7 +67,6 @@ import java.lang.invoke.MethodType;
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
@ -52,8 +84,9 @@ import jdk.dynalink.linker.LinkerServices;
* becomes unreachable.
*/
public class TypeConverterFactoryMemoryLeakTest {
// Usually succeeds in less than a second, but give it time
private static final Duration MAX_DURATION = Duration.ofSeconds(15);
// With explicit GC calls succeeds in 11-12 iterations depending on GC used.
// 1000 should be a safe upper limit after which we can consider it failed.
private static final int MAX_ITERATIONS = 1000;
private static final ReferenceQueue<MethodHandle> refQueue = new ReferenceQueue<>();
private static final List<Reference<MethodHandle>> refs = new ArrayList<>();
@ -74,11 +107,10 @@ public class TypeConverterFactoryMemoryLeakTest {
}
public static void main(String[] args) {
long start = System.nanoTime();
long deadline = start + MAX_DURATION.toNanos();
while (System.nanoTime() < deadline) {
for (int count = 0; count < MAX_ITERATIONS; count++) {
// Just create them as fast as possible without retaining.
makeOne();
System.gc();
if (refQueue.poll() != null) {
// Success, a method handle became phantom reachable.
return;

@ -22,10 +22,43 @@
*/
/*
* @test
* @test id=with_SerialGC
* @requires vm.gc.Serial
* @bug 8198540
* @summary Test TypeConverterFactory is not leaking class loaders
* @author Attila Szegedi
* @summary Test TypeConverterFactory is not leaking class loaders (Serial GC)
* @run main/othervm -XX:+UseSerialGC TypeConverterFactoryRetentionTests
*/
/*
* @test id=with_ParallelGC
* @requires vm.gc.Parallel
* @bug 8198540
* @summary Test TypeConverterFactory is not leaking class loaders (Parallel GC)
* @run main/othervm -XX:+UseParallelGC TypeConverterFactoryRetentionTests
*/
/*
* @test id=with_G1GC
* @requires vm.gc.G1
* @bug 8198540
* @summary Test TypeConverterFactory is not leaking class loaders (G1 GC)
* @run main/othervm -XX:+UseG1GC TypeConverterFactoryRetentionTests
*/
/*
* @test id=with_ZGC
* @requires vm.gc.Z
* @bug 8198540
* @summary Test TypeConverterFactory is not leaking class loaders (Z GC)
* @run main/othervm -XX:+UseZGC TypeConverterFactoryRetentionTests
*/
/*
* @test id=with_ShenandoahGC
* @requires vm.gc.Shenandoah
* @bug 8198540
* @summary Test TypeConverterFactory is not leaking class loaders (Shenandoah GC)
* @run main/othervm -XX:+UseShenandoahGC TypeConverterFactoryRetentionTests
*/
import java.lang.invoke.MethodHandle;
@ -33,7 +66,6 @@ import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
@ -50,8 +82,9 @@ import jdk.dynalink.linker.LinkerServices;
* from getting garbage collected.
*/
public class TypeConverterFactoryRetentionTests {
// Usually succeeds in less than a second, but give it time
private static final Duration MAX_DURATION = Duration.ofSeconds(15);
// With explicit GC calls succeeds in 1-2 iterations depending on GC used.
// 1000 should be a safe upper limit after which we can consider it failed.
private static final int MAX_ITERATIONS = 1000;
private static class TestLinker implements GuardingDynamicLinker, GuardingTypeConverterFactory {
public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices) {
@ -134,15 +167,14 @@ public class TypeConverterFactoryRetentionTests {
LinkerServices linkerServices = createLinkerServices();
long start = System.nanoTime();
long deadline = start + MAX_DURATION.toNanos();
while (System.nanoTime() < deadline) {
for (int count = 0; count < MAX_ITERATIONS; count++) {
TestClassLoader cl = new TestClassLoader(y.getClassLoader(), "X");
Class<?> x = Class.forName("X", true, cl);
assert x.getClassLoader() == cl;
linkerServices.getTypeConverter(y, x);
linkerServices.getTypeConverter(x, y);
refs.add(new PhantomReference<>(cl, refQueue));
System.gc();
if (refQueue.poll() != null) {
return;
}
@ -165,9 +197,7 @@ public class TypeConverterFactoryRetentionTests {
LinkerServices linkerServices = createLinkerServices();
long start = System.nanoTime();
long deadline = start + MAX_DURATION.toNanos();
while (System.nanoTime() < deadline) {
for (int count = 0; count < MAX_ITERATIONS; count++) {
TestClassLoader cl1 = new TestClassLoader(null, "X");
Class<?> x = Class.forName("X", true, cl1);
assert x.getClassLoader() == cl1;
@ -178,6 +208,7 @@ public class TypeConverterFactoryRetentionTests {
linkerServices.getTypeConverter(x, y);
refs.add(new PhantomReference<>(cl1, refQueue1));
refs.add(new PhantomReference<>(cl2, refQueue2));
System.gc();
if (refQueue1.poll() != null) {
gc1 = true;
}