2009-06-11 7 views
2

J'ai un plugin eclipse, qui se connecte à un composant COM en utilisant Jacob. Mais après avoir fermé le plugin entièrement, le fichier .exe reste suspendu dans les processus Windows.JACOB ne libère pas les objets correctement

J'utilise ComThread.InitMTA(true) pour l'initialisation et m'assure que SafeRelease() est appelée pour chaque objet COM que j'ai créé avant de fermer l'application et que j'appelle ComThread.Release() à la toute fin.

Est-ce que je laisse quelque chose de perdu?

Répondre

4

Avait le même problème avec le convertisseur TD2JIRA. Finalement, il a fallu patcher l'un des fichiers Jacob pour libérer les objets. Après tout, tout s'est bien passé.

Le code dans ma méthode logout() client ressemble maintenant à ceci:

try { 
    Class rot = ROT.class; 
    Method clear = rot.getDeclaredMethod("clearObjects", new Class[]{}); 
    clear.setAccessible(true); 
    clear.invoke(null, new Object[]{}); 
} catch(Exception ex) { 
    ex.printStackTrace(); 
} 

La classe ROT était pas accessible au départ, AFAIR.

Mise à jour

La bonne façon de libérer des ressources en Jacob est d'appeler

ComThread.InitSTA(); // or ComThread.InitMTA() 
... 
ComThread.Release(); 

Bad chose est cependant que, parfois, il ne permet pas. Bien que Jacob appelle la méthode native release(), la mémoire (pas même la mémoire Java, mais la mémoire de processus JVM) ne se développe de manière incontrôlable.

+0

Merci Vladimir pour vos commentaires. J'ai utilisé une application de test, et .exe est fermé juste après la fermeture de l'application de test.Pour Jacob, votre solution semble fonctionner, .exe est enlevé dans les 5 minutes, et aucun changement d'utilisation de la mémoire n'est vu pendant ce temps dans le gestionnaire de tâches. La durée de 5 minutes est-elle normale? peut-être un problème de Jacob? – Gorro

+0

Je dois admettre que la solution était basée sur l'intuition (après plusieurs essais), et je n'ai aucune connaissance qui la supporte ou l'explique. :( –

+0

comment avez-vous patcher les fichiers jacob, vous souvenez-vous? – rogerdpack

5

Quelques autres suggestions:

  1. Déplacer l'appel à ComThread.Release() dans un bloc finally, sinon le fil restent attachés si une exception est levée. Vérifiez que vous appelez ComThread.InitMTA et ComThread.Release dans chaque thread qui utilise un objet COM. Si vous oubliez de le faire dans un thread de travail, ce thread sera automatiquement attaché et jamais détaché.

  2. Évitez InitSTA et respectez InitMTA. Même quand il n'y a qu'un seul thread utilisant COM, j'ai trouvé InitSTA être floconneux. Je ne sais pas comment le mécanisme de triage interne de JACOB fonctionne mais j'ai fini avec des objets "fantômes" qui semblent être valides mais ne font rien quand leurs méthodes sont invoquées.

Heureusement, je n'ai encore jamais eu besoin de modifier un code dans la bibliothèque JACOB.

+1

Même avec InitMTA et la séquence d'ouverture/fermeture correcte, j'ai trouvé que la mémoire est consommée assez rapidement.Par conséquent, ce que je fais maintenant est de provoquer un traitement de processus enfant DCOM communication, et parlez-lui via le protocole de texte.Lorsqu'un certain nombre d'appels passés, je le tue sans pitié et le réapparaître.Le serveur que j'utilise permet, heureusement. –

6

J'ai moi-même rencontré ce problème. Après avoir joué avec initMTA, etc. J'ai trouvé une solution simple - quand vous démarrez Java ajoutez ce qui suit à votre ligne de commande: -Dcom.jacob.autogc = true

Ceci entraînera la classe ROT à utiliser un WeakHashMap au lieu d'un HashMap et cela résout le problème .

Vous pouvez également utiliser -Dcom.jacob.debug = true pour voir beaucoup de débogage informatif et regarder la taille de la carte ROT.

Questions connexes