Unloading dll in Java

2019-07-30 13:22发布

问题:

According to this and this, it seems that a dll is only unloaded when the reference to the ClassLoader object is gone and the garbage collector runs. If this is the case, can you simply load the dll in a thread, and then kill the thread to achieve the same effect without having to create a custom ClassLoader? Something like this:


new Thread(
    new Runnable()
    {
        public void run() 
        {
            System.load("dll");
        }
    }
).start(); //Will load the dll, then there will be no references to the thread

System.gc(); //Will unload the dll

I would probably do something more elaborate than this in a real life setting, but just to show the point.

回答1:

No. That won't work. The dll is bound to the class object you have in memory with the native interface. As long as that class remains in memory, the dll won't unload.

This is very akin to servlet container that can reload classes (as part of development) - they always have a separate class loader per web context (look at tomcat's class loader documentation).

Think of it as a ball of spaghetti - every single reference is a spaghetti, and only if the whole ball is free, can the whole mess go away.

Drop all references to objects of any class that class loader has loaded, and finally the reference to the class loader itself.

Only then will the gc get rid of it (and System.gc() doesn't guarantee it runs, it may run sometime in the future)

This can be really tricky to achieve - many times you end up with memory leaks since there's some tiny forgotten spaghetti keeping the whole ball alive.