2010-04-23 3 views
0

Y at-il un moyen de détecter et de gérer si une bibliothèque Java libère correctement des handles de fichiers (via "close") de dans un programme Java qui utilise cette bibliothèque , à moins d'avoir accès au code de la bibliothèque et d'insérer les instructions "finally close" correspondantes?Détection et gestion des fuites de fichier de bibliothèque tierces en Java

Si la détection est possible, est-il possible de fermer ces fichiers poignées sans référence au lecteur (ou FileInputStream) qui était en train de lire le fichier?

Répondre

3

Sous Linux et probablement quelques unix, vous pouvez utiliser lsof à « la liste des fichiers ouverts » ouverts par une application. Vous verrez probablement leur nombre augmenter si votre application fuit des descripteurs de fichiers. Vous pouvez même atteindre le plafond (par défaut) de 1024 poignées éventuellement.

Sous Windows, il y a quelques utilitaires similaires libres quelque part dans la suite SysInternals; Je pense que cela s'appelle "poignées" ou "fhandles" ou autres. Je vais voir si je peux le trouver ...


EDIT: Ah, la voici: Handle.


EDIT: J'ai récemment rencontré un problème similaire, obscur avec prises (qui sont aussi une sorte de poignée de fichiers, au moins sous Linux): Il s'avère que même si la connexion a été fermée, l'associé les handles de fichiers ne seraient pas libérés avant que Java ait fait un garbage collection. Notre application ne passait pas par beaucoup de mémoire, si souvent que les poignées de connexion s'accumulent plus vite qu'elles ont été nettoyées. Nous avons résolu le problème en insérant un System.gc() de temps en temps. Le coup de performance était tolérable par rapport à un dysfonctionnement à fond quand l'application a manqué de poignées.


EDIT: A son plus haut niveau, la bibliothèque du JRE est bien sûr "juste" code Java et le code source est toujours en cours de publication AFAIK. Donc, si vous êtes vraiment désespéré, vous pouvez écrire vos propres wrappers autour des choses comme FileInputStream et FileReader, etc. Je crois qu'il ya un nom de répertoire dans l'arborescence de fichiers du JRE dans lequel vous pouvez mettre Jars de « tripoté » classes; C'est ce qu'on appelle «approuvé» ou quelque chose comme ça. Cela, ou vous pouvez faire des changements de code source dans le code de la bibliothèque JRE et créer vos propres fichiers de remplacement pour les bibliothèques Sun (ou autres). Ce n'est évidemment pas propre ou très portable. Je n'ai aucune expérience personnelle avec de telles mesures, et je ne les recommanderais pas non plus.

+0

Je suis au courant de lsof (et la manière/proc pour regarder les choses) - qui serait en effet le travail, d'une manière non-portable, pour détecter la fuite d'un programme. Je voudrais, cependant, beaucoup plus une solution java-only, et idéalement un java-seul correctif – tucuxi

+0

Nice - Je n'étais pas au courant de ce programme de poignée pour Windows. Pourtant, y a-t-il une façon intra-java de faire les choses? – tucuxi

+0

Gotcha. Dans ce cas, j'ai mal compris votre question. Cependant, je doute que vous ayez besoin de le faire par programmation. Soit vous trouvez, dans un cycle d'essai contrôlé manuellement, que le programme fuit des poignées, et vous vous plaignez au fabricant de votre bibliothèque jusqu'à ce qu'il répare le problème.Ou vous ne trouvez pas de preuve de fuite des poignées, auquel cas vous n'aurez pas besoin de construire un kludge dans votre programme. Pour répondre à cette question: Non, je ne pense pas qu'il existe une façon neutre de faire cela à partir d'un programme Java. La bibliothèque ne fait pas tout son possible pour exposer ce genre de choses. –

1

Vous pouvez exécuter FindBugs sur la bibliothèque.

+0

Cela nécessiterait des sources pour la bibliothèque :-( – tucuxi

+0

http://findbugs.sourceforge.net/factSheet.html "FindBugs fonctionne en analysant le bytecode Java (fichiers de classe compilés), de sorte que vous n'avez même pas besoin du code source du programme pour l'utiliser. " –

+0

bkail a raison, vous pouvez exécuter FindBugs sur les fichiers de classe ou sur un fichier jar complet. FindBugs vous avertira de toutes les ressources qui ne sont pas fermées correctement.Cela ne vous aidera pas à les corriger, mais il laissera vous savez à coup sûr qu'ils existent. –

4

Je pense que file leak detector de Kohsuke est très proche de ce qui a été demandé (il y a près de 4 ans). C'est un agent Java qui garde la trace de où/quand/qui a ouvert les fichiers dans votre JVM.Vous pouvez demander à l'agent de suivre ces opérations pour connaître le modèle d'accès ou gérer les fuites, et vider la liste des fichiers ouverts./quand/qui les a ouverts ". Plus d'infos dans le lien ci-dessus.

Questions connexes