/*
* Copyright (c) 2001, 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.
*/
/*
* Warning! Using this component need VM option -XX:-UseGCOverheadLimit
*
*/
package nsk.share;
import java.lang.ref.PhantomReference;
import java.util.*;
import nsk.share.gc.gp.*;
import nsk.share.test.ExecutionController;
import nsk.share.test.Stresser;
import jdk.test.lib.Utils;
import jdk.test.whitebox.WhiteBox;
/**
* The ClassUnloader class allows to force VM to unload class(es)
* using WhiteBox.fullGC technique.
*
*
The method unloadClass() is provided which calls
* WhiteBox.fullGC to cleanup the heap. So, if all references to a class
* and its loader are canceled, this may result in unloading the class.
*
*
ClassUnloader mainly intends to unload a class which was loaded
* with especial ClassUnloader.loadClass() method.
* A class is eligible for unloading if its class loader has been reclaimed.
* A Cleaner is used to inform the main test code when the class loader
* becomes unreachable and is reclaimed.
* If, after setting the class loader to null, no notification that it has become
* reclaimed is received within the timeout interval, then the class is considered
* to still be loaded and unloadClass() returns false.
*
*
Such reclaiming control applies only to a class loaded by
* ClassUnloader's loadClass() method. Otherwise, if there
* was no such class loaded, unloadClass() doesn't wait
* for a timeout and always returns false.
*
*
By default internal class loader of CustomClassLoader class
* is used for loading classes. This class loader can load class from .class file
* located in the specified directory.
* Application may define its own class loader, which may load classes using
* any other technique. Such class loader should be derived from base
* CustomClassLoader class, and set by setClassLoader()
* method.
*
* @see #setClassLoader(CustomClassLoader)
* @see #loadClass(String)
* @see #loadClass(String, String)
* @see #unloadClass()
*/
public class ClassUnloader {
/**
* Class name of default class loader.
*/
public static final String INTERNAL_CLASS_LOADER_NAME = "nsk.share.CustomClassLoader";
/**
* Phantom reference to the class loader.
*/
private PhantomReference