Existe-t-il une fuite de descripteur de fichier lors de l’utilisation de sockets sur une plate-forme Linux?

StackOverflow https://stackoverflow.com/questions/429762

Question

Si j'ouvre et ferme un socket en appelant par exemple

Socket s = new Socket( ... );
s.setReuseAddress(true);
in = s.getInputStream();
...
in.close(); 
s.close();      

Linux indique que ce socket est toujours ouvert ou au moins que le descripteur de fichier pour la connexion est présent. Lors de l'interrogation des fichiers ouverts pour ce processus par lsof, il existe une entrée pour la connexion fermée:

COMMAND  PID   USER   FD   TYPE DEVICE     SIZE   NODE NAME
java    9268 user    5u  sock    0,4           93417 can't identify protocol

Cette entrée est conservée jusqu'à la fermeture du programme. Existe-t-il un autre moyen de fermer enfin la prise? Je suis un peu inquiet que mon application Java puisse bloquer plusieurs descripteurs de fichiers. Est-ce possible? Ou bien Java conserve-t-il ces sockets pour les réutiliser même si ReuseAdress est défini?

Était-ce utile?

La solution

Si ces sockets sont tous à l'état TIME_WAIT, cela est normal, du moins pendant un certain temps. Vérifiez cela avec netstat; il est courant que les sockets restent pendant quelques minutes pour s'assurer que les données éparpillées du socket sont correctement jetées avant de réutiliser le port pour un nouveau socket.

Autres conseils

Vous pouvez également vérifier /proc/<pid>/fd, le répertoire contiendra tous les descripteurs de fichiers actuellement ouverts. Si un fichier disparaît après la fermeture du socket, vous ne rencontrerez aucun problème (du moins pas avec vos descripteurs de fichier:).

Je pense que ce n'est pas le problème de votre programme.

Dans SUN_Java, lorsque la bibliothèque native liée au socket est chargée, un fichier fictif MAGIC_SOCK est créé.

écrire sur le MAGIC_SOCK entraînera une exception Connect Rest et lire sur le MAGIC_SOCK entraînera un EOF.

le pair de magic_sock a été complètement fermé, et le magic_sock lui-même est à moitié fermé, et l'état restera & "; impossible d'identifier le protocole &";.

Peut-être que c'est un socket d'un autre protocole (& "; Impossible d'identifier le protocole &"; hein?) utilisé en interne dans l'implémentation pour faire quelque chose, qui est créé sur le premier socket.

Avez-vous essayé à plusieurs reprises de créer et de fermer des sockets pour voir si ces sockets persistaient vraiment? Il semble probable que ce soit un cas isolé.

Java utilise probablement des sockets en interne pour beaucoup de choses - il peut s’agir d’un Unix, de Netlink (sous Linux) ou d’un autre type de socket.

Créez un petit script bash pour surveiller les sockets ouverts pour une certaine application ou pid, et laissez-le s'exécuter pendant le test de votre application java.

Je doute de toute façon qu'il y ait des fuites dans cette chose car les sockets sont très utilisés dans le monde Linux / Unix et que ce genre de problème bouillonnerait très vite

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top