2

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.

Community
  • 1
  • 1
user489041
  • 27,916
  • 55
  • 135
  • 204
  • Note: `System.gc();` will not directly force a garbare collection, it's more like "please run a garbage collection in the near future if you're in the mood" – thejh Nov 29 '10 at 19:20
  • 2
    "Oh mighty VM. I humbly submit to you, with utmost respect, that you may perhaps, if possible, at any time convenient to you, no pressure, consider, in your infinite wisdom, to run a garbage collect, pretty please, with sugar on top." – Martin Algesten Nov 29 '10 at 20:09

1 Answers1

3

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.

Martin Algesten
  • 13,052
  • 4
  • 54
  • 77
  • Hmmm, this is interesting. I need to be able to load and unload a dll on the fly. Lets say I have two dll's. One is called "loader", the other is called "function". The sole purpose of the "loader" dll is to load and unload the "function" dll (so it doesnt have to be done in java). The "function" dll provides all the functionality I need. If I load the "function" dll via the "loader" dll, will JNI still allow me to access my native functions in the "function" dll as I have before? Sorry if this is confusing. Or do you have any suggestions for loading and loading a dll on the fly? – user489041 Nov 29 '10 at 20:42
  • I'd imagine you could do it like you describe. Java <-> Loader <-> Function. The loader is effectively just an interface, proxying the actual method calls to function, so function is never in direct contact with java. That way you would control in C/C++/whateva when function is loaded. This is interesting, let us know how it works! – Martin Algesten Nov 30 '10 at 03:57
  • @user489041 : did you found out any solution.? I am very eager to know..:) – Saurabh Kumar Jan 17 '12 at 23:52
  • @Saurabh Kumar I started to implement this. Had `some` success with it. Never got it fully working though. Got moved onto a different project. I dont really have anything concrete to report on if it works or not. – user489041 Jan 18 '12 at 21:56