Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/javax/management/mxbean/LeakTest.java
38841 views
/*1* Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @bug 648224725* @summary Test that creating MXBeans does not introduce memory leaks.26* @author Eamonn McManus27* @run build LeakTest RandomMXBeanTest28* @run main LeakTest29*/3031/* In this test we create a ClassLoader, then use it to load and run another32* jtreg test. When the other test has completed, we wait for the ClassLoader33* to be garbage-collected. If it has not been gc'd after a reasonable34* amount of time, then something is keeping a reference to the ClassLoader,35* which implies a memory leak.36*37* This test can be applied to any jtreg test, not just the MXBean tests.38*/3940import java.lang.ref.Reference;41import java.lang.ref.ReferenceQueue;42import java.lang.ref.WeakReference;43import java.lang.reflect.Method;44import java.net.URL;45import java.net.URLClassLoader;4647public class LeakTest {48/* Ideally we would include MXBeanTest in the list of tests, since it49* has fairly complete coverage. However, the ClassLoader fails to be50* gc'd when we do that, and I am unable to figure out why. Examining51* a heap dump shows only weak references to the ClassLoader. I suspect52* something is wrong in the internals of the reflection classes, used53* quite heavily by MXBeanTest.54*/55// private static Class<?>[] otherTests = {MXBeanTest.class};5657private static Class<?>[] otherTests = {RandomMXBeanTest.class};5859// This class just makes it easier for us to spot our loader in heap dumps60private static class ShadowClassLoader extends URLClassLoader {61ShadowClassLoader(URL[] urls, ClassLoader parent) {62super(urls, parent);63}64}6566public static void main(String[] args) throws Exception {67System.out.println("Testing that no references are held to ClassLoaders " +68"by caches in the MXBean infrastructure");69for (Class<?> testClass : otherTests)70test(testClass);71if (failure != null)72throw new Exception("CLASSLOADER LEAK TEST FAILED: " + failure);73System.out.println("CLASSLOADER LEAK TEST PASSED");74if (args.length > 0) {75System.out.println("Waiting for input");76System.in.read();77}78}7980private static void test(Class<?> originalTestClass) throws Exception {81System.out.println();82System.out.println("TESTING " + originalTestClass.getName());83WeakReference<ClassLoader> wr = testShadow(originalTestClass);84System.out.println("Test passed, waiting for ClassLoader to disappear");85long deadline = System.currentTimeMillis() + 20*1000;86Reference<? extends ClassLoader> ref;87while (wr.get() != null && System.currentTimeMillis() < deadline) {88System.gc();89Thread.sleep(100);90}91if (wr.get() != null)92fail(originalTestClass.getName() + " kept ClassLoader reference");93}9495private static WeakReference<ClassLoader>96testShadow(Class<?> originalTestClass) throws Exception {97URLClassLoader originalLoader =98(URLClassLoader) originalTestClass.getClassLoader();99URL[] urls = originalLoader.getURLs();100URLClassLoader shadowLoader =101new ShadowClassLoader(urls, originalLoader.getParent());102System.out.println("Shadow loader is " + shadowLoader);103String className = originalTestClass.getName();104Class<?> testClass = Class.forName(className, false, shadowLoader);105if (testClass.getClassLoader() != shadowLoader) {106throw new IllegalArgumentException("Loader didn't work: " +107testClass.getClassLoader() + " != " + shadowLoader);108}109Method main = testClass.getMethod("main", String[].class);110main.invoke(null, (Object) new String[0]);111return new WeakReference<ClassLoader>(shadowLoader);112}113114private static void fail(String why) {115System.out.println("FAILED: " + why);116failure = why;117}118119private static String failure;120}121122123