2010-11-29 10 views
1

Nach this und this scheint es, dass eine DLL nur entladen wird, wenn der Verweis auf das ClassLoader-Objekt nicht mehr vorhanden ist und der Garbage Collector ausgeführt wird. Wenn dies der Fall ist, können Sie die DLL einfach in einen Thread laden und dann den Thread beenden, um denselben Effekt zu erzielen, ohne einen benutzerdefinierten ClassLoader erstellen zu müssen? Etwas wie folgt aus:Entladen dll in Java

 

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 
 

Ich würde wahrscheinlich etwas aufwendiger als dies in einem realen Leben Einstellung tun, sondern nur um den Punkt zu zeigen.

+0

Hinweis: 'System.gc();' wird nicht direkt eine Garbare-Sammlung erzwingen, es ist eher wie "bitte in naher Zukunft eine Garbage Collection ausführen, wenn Sie in der Stimmung sind" – thejh

+2

"Oh mächtige VM. Ich demütig unterbreiten Sie Ihnen, mit äußerster Achtung, dass Sie vielleicht, wenn möglich, zu jeder Zeit zu Ihnen bequem, keinen Druck, in Ihrer unendlichen Weisheit, einen Müll sammeln, bitte bitte, mit Zucker an der Spitze zu betrachten. –

Antwort

2

Nein. Das wird nicht funktionieren. Die DLL ist an das Klassenobjekt gebunden, das Sie mit der nativen Schnittstelle im Speicher haben. Solange diese Klasse im Speicher verbleibt, wird die DLL nicht entladen.

Dies ist dem Servlet-Container sehr ähnlich, der Klassen (als Teil der Entwicklung) neu laden kann - sie haben immer einen separaten Klassenlader pro Webkontext (siehe tomcat's class loader documentation).

Betrachten Sie es als eine Kugel Spaghetti - jede einzelne Referenz ist eine Spaghetti, und nur wenn der ganze Ball frei ist, kann das ganze Durcheinander verschwinden.

Löschen Sie alle Verweise auf Objekte einer Klasse, die der Klassenlader geladen hat, und schließlich den Verweis auf den Klassenlader selbst.

Nur dann wird die gc es loszuwerden (und System.gc() garantiert nicht, es läuft, kann es irgendwann in der Zukunft läuft)

Dies kann wirklich schwierig zu erreichen - oft Sie mit Speicher am Ende Lecks, da es ein paar kleine vergessene Spaghetti gibt, die den ganzen Ball am Leben erhalten.

+0

Hmmm, das ist interessant. Ich muss in der Lage sein, eine DLL im laufenden Betrieb zu laden und zu entladen. Sagen wir, ich habe zwei DLLs. Einer heißt "loader", der andere heißt "function". Der einzige Zweck der "loader" DLL ist das Laden und Entladen der "Funktion" DLL (so muss es nicht in Java getan werden). Die "Funktion" DLL bietet alle Funktionen, die ich brauche. Wenn ich die "Funktion" dll über die "loader" DLL lade, wird JNI mir weiterhin erlauben, auf meine nativen Funktionen in der "Funktions" dll zuzugreifen, wie ich es vorher getan habe? Tut mir leid, wenn das verwirrend ist. Oder haben Sie irgendwelche Vorschläge zum Laden und Laden einer DLL im laufenden Betrieb? – user489041

+0

Ich könnte mir vorstellen, du könntest es so machen, wie du es beschreibst. Java <-> Loader <-> Funktion. Der Loader ist im Grunde nur eine Schnittstelle, die die tatsächlichen Methodenaufrufe zur Funktion führt, so dass die Funktion niemals in direktem Kontakt mit Java steht. Auf diese Weise würden Sie in C/C++/whateva steuern, wenn die Funktion geladen ist. Das ist interessant, lassen Sie uns wissen, wie es funktioniert! –

+0

@ user489041: Haben Sie irgendeine Lösung gefunden? Ich bin sehr gespannt darauf, zu wissen .. :) –