The best way is to launch another JVM, communicate with it with socket(for example), and kill the JVM after it's done.
It'll be interesting to discuss whether we can sandbox it within the same JVM.
After you are done with using the 3rd party library, and you are no longer referencing any objects from that library, what could be the garbage that's still lingering?
Their classes - even though you are not referening any of them, if they are loaded by the same classloader as your code, these classes will persist. And their static fields could reference more lingering data, and so forth
ThreadLocal - it could have set some thread local variables, and not cleaned them up
Thread - it could have spawned some threads that persist
In some global place - e.g. System.setProperty() - it'll stay there.
So in general, it's probably difficult.
However, we can use a separate classloader and a separate thread to execute the 3rd party library, and this strategy can probably unload all garbages created by the 3rd party, in most cases.
Are there existing tools for doing that? I'm not too knowledgeable about that. I do have some experience with implementing a hot reloadable server, and I have some utility classes that can be used for this purpose. For example
// wrap 3rd party code, expose it as some java.*.* interface
public class MyWrapper implements Callable<String>
{
@Override
public String call()
{
return ThirdParty.query(..);
}
}
HotReloader hot = new HotReloader();
Callable<String> func = (Callable<String>)hot.getAppInstance("pkg.MyWrapper");
String result = func.call();
// then dereference `hot` and `func`
see HotReloader
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…