Class Loader Unloading

My ultimate goal is to reload classes after they are already loaded into the JVM.

Having read the following answer Unloading classes in java? , I'm trying to implement my own Class-Loader, which itself creates another instance of the Loader class (of the same type) for each class that it loads.

therefore, the result is one class per loader class.

The goal is to be able to have a GC class, that is, all its instances, and then unload its classloader and be able to reload the same class from its bytes.

The problem is this: I can see that my class instance is garbage collection using the finalize () method, but I cannot load my class loader or collect garbage. is there any code example, a simple test that shows how this can be done?

thanks, any help would be appreciated

Edit

to be more clear, I'm interested in code examples in which the creation of new objects occurs via the operand 'new ()', and the class loader does not explicitly reload the class basically, but after calling the next "new ()".

+7
source share
2 answers

Class loaders should be garbage collected if there are no more references to them. I took this code from @PeterLawrey (thanks) (it does the same as yours), put the log in the user classloader finalize() method and voila, classloaders are garbage collected after their loaded class is gc :

  /* Copyright (c) 2011. Peter Lawrey * * "THE BEER-WARE LICENSE" (Revision 128) * As long as you retain this notice you can do whatever you want with this stuff. * If we meet some day, and you think this stuff is worth it, you can buy me a beer in return * There is no warranty. */ import java.lang.reflect.Field; import java.net.URL; import java.net.URLClassLoader; public class LoadAndUnloadMain { public static void main(String... args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InterruptedException { URL url = LoadAndUnloadMain.class.getProtectionDomain().getCodeSource().getLocation(); final String className = LoadAndUnloadMain.class.getPackage().getName() + ".UtilityClass"; { ClassLoader cl; Class clazz; for (int i = 0; i < 2; i++) { cl = new CustomClassLoader(url); clazz = cl.loadClass(className); loadClass(clazz); cl = new CustomClassLoader(url); clazz = cl.loadClass(className); loadClass(clazz); triggerGC(); } } triggerGC(); } private static void triggerGC() throws InterruptedException { System.out.println("\n-- Starting GC"); System.gc(); Thread.sleep(100); System.out.println("-- End of GC\n"); } private static void loadClass(Class clazz) throws NoSuchFieldException, IllegalAccessException { final Field id = clazz.getDeclaredField("ID"); id.setAccessible(true); id.get(null); } private static class CustomClassLoader extends URLClassLoader { public CustomClassLoader(URL url) { super(new URL[]{url}, null); } @Override protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { try { return super.loadClass(name, resolve); } catch (ClassNotFoundException e) { return Class.forName(name, resolve, LoadAndUnloadMain.class.getClassLoader()); } } @Override protected void finalize() throws Throwable { super.finalize(); System.out.println(this.toString() + " - CL Finalized."); } } } class UtilityClass { static final String ID = Integer.toHexString(System.identityHashCode(UtilityClass.class)); private static final Object FINAL = new Object() { @Override protected void finalize() throws Throwable { super.finalize(); System.out.println(ID + " Finalized."); } }; static { System.out.println(ID + " Initialising"); } } 
+9
source

In the IBM J9 VM, everything happens differently, since the class loader is unloaded only during global gc. This can lead to huge pause times in the global gc and memory when there are a large number of class creators. I ran into these problems with JMXMP, where for each deleted message of type MBeanServerRequestMessage.CREATE_MBEAN_LOADER_PARAMS , one instance of the class com.sun.jmx.remote.opt.util.OrderClassLoaders classloader is created.

+1
source

All Articles