2009-01-09 17 views
6

Si abrir y cerrar un socket llamando por ejemplo¿Hay una fuga de descriptor de archivo cuando se usan sockets en una plataforma Linux?

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

Linux afirma que esta toma está todavía abierto o al menos el descriptor de archivo para la conexión es presen. Cuando se consultan los archivos abiertos para este proceso mediante lsof, hay una entrada para la conexión cerrada:

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

Esta entrada se mantiene hasta que el programa se cierra. ¿Hay alguna otra manera de finalmente cerrar el zócalo? Estoy un poco preocupado de que mi aplicación java pueda bloquear muchos descriptores de archivos. es posible? ¿O Java mantiene estas tomas para reutilizarlas incluso si ReuseAdress está configurado?

Respuesta

5

Si todos los conectores están en el estado TIME_WAIT, esto es normal, al menos por un tiempo. Compruébalo con netstat; Es habitual que los sockets permanezcan unos minutos para garantizar que los datos remanentes del socket se eliminen con éxito antes de reutilizar el puerto para un nuevo socket.

+0

De acuerdo, esto es lo primero que debe verificar. Y después de unos minutos, los enchufes deberían desaparecer, antes de que su programa termine necesariamente. –

+0

El autor declara que las entradas permanecen hasta que el programa se cierra, aunque supongo que no especifica si eso es más que unos pocos minutos. –

+0

Sí, vi el programa "cierra el programa", pero no estaba seguro. –

0

Tal vez es un socket de algún otro protocolo ("No se puede identificar el protocolo" ¿eh?) Utilizado internamente en la implementación para hacer algo, que se crea en el primer socket.

¿Ha intentado crear en repetidas ocasiones receptáculos y cerrarlos, para ver si realmente estos enchufes persisten? Parece probable que esto sea único.

Java probablemente usa sockets internamente para muchas cosas: pueden ser Unix, Netlink (bajo Linux) u otro tipo de socket.

0

Crea un pequeño script bash para monitorear los sockets abiertos para una determinada aplicación o pid, y deja que se ejecute mientras pruebas tu aplicación java.

dudo de todas formas que no son cualquier tipo de fugas en esta cosa como tomas son muy utilizados en linux mundo/Unix y este tipo de problema sería brotan muy QUICKY

3

También es posible que desee comprobar /proc/<pid>/fd, la directorio contendrá todos sus descriptores de archivo abiertos actualmente. Si un archivo desaparece después de cerrar el zócalo, no se encontrará con ningún problema (al menos no con los descriptores de archivos :).

1

Creo que no es problema de su programa.

En SUN_Java, cuando se carga la lib nativa relacionada con el socket, se creará una FD MAGIC_SOCK.

escribir en MAGIC_SOCK resultará en una excepción de Connect Exception, y leer en MAGIC_SOCK resultará en EOF.

el par de magic_sock ha sido cerrado por completo, y el magic_sock en sí mismo está medio cerrado, y el estado seguirá siendo "no se puede identificar el protocolo".

Cuestiones relacionadas