in src/main/java/org/apache/cassandra/distributed/shared/InstanceClassLoader.java [219:248]
public void close() throws IOException
{
isClosed = true;
super.close();
try
{
// The JVM really wants to prevent Class instances from being GCed until the
// classloader which loaded them is GCed. It therefore maintains a list
// of Class instances for the sole purpose of providing a GC root for them.
// Here, we actually want the class instances to be GCed even if this classloader
// somehow gets stuck with a GC root, so we clear the class list via reflection.
// The current features implemented technically work without this, but the Garbage
// Collector works more efficiently with it here, and it may provide value to new
// feature developers.
Field f = getField(ClassLoader.class, "classes");
f.setAccessible(true);
List<Class<?>> classes = (List<Class<?>>) f.get(this);
classes.clear();
// Same problem with packages - without clearing this,
// the instance classloader can't unload
f = getField(ClassLoader.class, "packages");
f.setAccessible(true);
Map<?,?> packageMap = (Map<?, ?>) f.get(this);
packageMap.clear();
}
catch (Throwable e)
{
throw new RuntimeException(e);
}
}