admin管理员组文章数量:1122846
I am trying to learn how class unloading works in Java. I have created a test application that just loads a class, and than waits.
package com.expirement;
import java.URL;
import java.URLClassLoader;
public class Main {
public static void main(String[]args) throws Exception {
f();
try{
Thread.sleep(5000);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
//breakpoint
}
public static void f() throws Exception {
URLClassLoader cl=new URLClassLoader(new URL[]{
Main.class.getProtectionDomain().getCodeSource().getLocation()
});
Class<?> c = cl.loadClass ("com.expirement.Loadable1");
cl.close();
System.gc();
cl = null;
c = null;
}
}
Unfortunately, on that breakpoint the JVM hasn't unloaded the class.
My questions are:
- Why has the class not been unloaded?
- What to do so that it can finally destroy the class (without stopping the runtime)?
I am trying to learn how class unloading works in Java. I have created a test application that just loads a class, and than waits.
package com.expirement;
import java.net.URL;
import java.net.URLClassLoader;
public class Main {
public static void main(String[]args) throws Exception {
f();
try{
Thread.sleep(5000);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
//breakpoint
}
public static void f() throws Exception {
URLClassLoader cl=new URLClassLoader(new URL[]{
Main.class.getProtectionDomain().getCodeSource().getLocation()
});
Class<?> c = cl.loadClass ("com.expirement.Loadable1");
cl.close();
System.gc();
cl = null;
c = null;
}
}
Unfortunately, on that breakpoint the JVM hasn't unloaded the class.
My questions are:
- Why has the class not been unloaded?
- What to do so that it can finally destroy the class (without stopping the runtime)?
1 Answer
Reset to default 3When you do not specify a parent loader, the URLClassLoader
will use the application class loader and since you are using a URL from the classpath, the requested class can be resolved through this parent loader.
You can specify the bootstrap loader (represented as null
) as the parent loader.
Note further that the chances of the objects getting collected are higher when you set the variables to null
or leave the method containing them before you trigger the garbage collection.
For example:
public class Main {
public static void main(String[] args) throws Exception {
ReferenceQueue<Class<?>> queue = new ReferenceQueue<>();
WeakReference<Class<?>> ref = f(queue);
do System.gc(); while(queue.remove(1000) != ref);
System.out.println("class has been collected");
}
public static
WeakReference<Class<?>> f(ReferenceQueue<Class<?>>queue) throws Exception {
URL url = Main.class.getProtectionDomain().getCodeSource().getLocation();
try(URLClassLoader cl=new URLClassLoader(new URL[]{ url }, null)) {
Class<?> c = cl.loadClass("com.expirement.Loadable1");
return new WeakReference<>(c, queue);
}
}
}
But always keep in mind that this is not guaranteed to collect the class. System.gc()
is just a hint that might get ignored by the JVM, but even when the garbage collector runs, it does not guaranty that all objects get collected, and finally, class unloading is an optional feature, which is not supported by every JVM and can be turned off in some implementations.
本文标签: javaWhy isn39t my class unloaded when I erase any link to them and to ClassLoaderStack Overflow
版权声明:本文标题:java - Why isn't my class unloaded when I erase any link to them and to ClassLoader? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736309684a1934106.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
System.gc()
does anything nor that class unloading will happen. But your chances are higher when you set the variables tonull
before runningSystem.gc()
. Further, check whetherc.getClassLoader() == cl
as you assume. I think, the default delegation parent is the application class loader and since the parent loader has a class of that name (the loaders load from the same URL), I’d expect the returned class to be loaded by the application class loader. – Holger Commented Nov 21, 2024 at 15:13URLClassLoader cl=new URLClassLoader(new URL[]{ Main.class.getProtectionDomain().getCodeSource().getLocation() }, null);
– Holger Commented Nov 21, 2024 at 15:28