2010-11-29 4 views
1

Selon this et this, il semble qu'une DLL n'est déchargée que lorsque la référence à l'objet ClassLoader a disparu et le garbage collector s'exécute. Si c'est le cas, pouvez-vous simplement charger la DLL dans un thread, puis tuer le thread pour obtenir le même effet sans avoir à créer un ClassLoader personnalisé? Quelque chose comme ceci:Déchargement dll en 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 
 

je probablement faire quelque chose de plus complexe que cela dans un vrai milieu de vie, mais juste pour montrer le point.

+0

Note: 'System.gc();' ne forcera pas directement une collection garbare, c'est plus comme "s'il vous plaît exécuter une collection de garbage dans un avenir proche si vous êtes d'humeur" – thejh

+2

"Oh mighty VM. Soumettez-vous, avec le plus grand respect, que vous puissiez peut-être, si possible, à n'importe quel moment vous convenant, pas de pression, considérez, dans votre infinie sagesse, de ramasser des ordures, s'il vous plaît, avec du sucre dessus. –

Répondre

2

Non. Cela ne fonctionnera pas. La DLL est liée à l'objet de classe que vous avez en mémoire avec l'interface native. Tant que cette classe reste en mémoire, la DLL ne sera pas déchargée.

Cela ressemble beaucoup à un conteneur de servlets qui peut recharger des classes (dans le cadre du développement) - ils ont toujours un chargeur de classe séparé par contexte Web (voir tomcat's class loader documentation). Pensez-y comme une boule de spaghetti - chaque référence est un spaghetti, et seulement si toute la boule est libre, tout le gâchis peut disparaître.

Supprimez toutes les références aux objets de toute classe chargée par le chargeur de classe, et enfin la référence au chargeur de classe lui-même.

Alors seulement, la gc se débarrasser (et System.gc() ne garantit pas qu'il fonctionne, il peut fonctionner dans le futur)

Cela peut être très difficile à réaliser - plusieurs fois, vous finissez avec mémoire fuites car il y a de minuscules spaghettis oubliés qui gardent toute la balle en vie.

+0

Hmmm, c'est intéressant. J'ai besoin de pouvoir charger et décharger une DLL à la volée. Disons que j'ai deux DLL. L'un s'appelle "loader", l'autre s'appelle "function". Le seul but de la DLL "loader" est de charger et de décharger la DLL "function" (donc cela ne doit pas être fait en java). La fonction "dll" fournit toutes les fonctionnalités dont j'ai besoin. Si je charge la fonction "dll" via la DLL "loader", est-ce que JNI me permettra quand même d'accéder à mes fonctions natives dans la DLL "function" comme je l'ai déjà fait? Désolé si cela est déroutant. Ou avez-vous des suggestions pour charger et charger une DLL à la volée? – user489041

+0

J'imagine que vous pourriez le faire comme vous le décrivez. Java <-> Chargeur <-> Fonction. Le chargeur est en fait juste une interface, procurant la fonction des appels de méthode réels, de sorte que la fonction n'est jamais en contact direct avec Java. De cette façon, vous contrôlez en C/C++/whateva lorsque la fonction est chargée. C'est intéressant, laissez-nous savoir comment cela fonctionne! –

+0

@ user489041: avez-vous trouvé une solution? Je suis très désireux de savoir .. :) –

Questions connexes