Есть ли утечка файлового дескриптора при использовании сокетов на платформе Linux? - PullRequest
6 голосов
/ 10 января 2009

Если я открываю и закрываю сокет, вызывая, например,

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

Linux заявляет, что этот сокет все еще открыт или, по крайней мере, представлен дескриптор файла для соединения. При запросе открытых файлов для этого процесса с помощью lsof, есть запись для закрытого соединения:

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

Эта запись сохраняется до закрытия программы. Есть ли другой способ окончательно закрыть сокет? Я немного обеспокоен тем, что мое Java-приложение может блокировать многие файловые дескрипторы. Это возможно? Или java сохраняет эти сокеты для повторного использования, даже если установлен ReuseAdress?

Ответы [ 5 ]

5 голосов
/ 10 января 2009

Если все эти сокеты находятся в состоянии TIME_WAIT, это нормально, по крайней мере, на некоторое время. Проверьте это с помощью netstat; Обычно сокеты остаются на несколько минут, чтобы обеспечить успешное удаление данных из сокета перед повторным использованием порта для нового сокета.

3 голосов
/ 10 января 2009

Вы также можете проверить /proc/<pid>/fd, каталог будет содержать все ваши текущие открытые дескрипторы файлов. Если файл исчезнет после того, как вы закроете сокет, у вас не возникнет никаких проблем (по крайней мере, с дескрипторами файлов:).

1 голос
/ 09 декабря 2011

Я думаю, что это не проблема вашей программы.

В SUN_Java, когда загружена собственная библиотека, связанная с сокетом, будет создан файл MAGIC_SOCK fd.

запись в MAGIC_SOCK приведет к исключению Connect Rest, а чтение в MAGIC_SOCK приведет к EOF.

Пир magic_sock полностью закрыт, а само magic_sock наполовину закрыто, и состояние останется "не может идентифицировать протокол".

0 голосов
/ 10 января 2009

Создайте небольшой скрипт bash для отслеживания открытых сокетов для определенного приложения или pid и дайте ему работать во время тестирования вашего java-приложения.

В любом случае, я сомневаюсь, что в этом есть какие-то утечки, так как сокеты очень часто используются в мире Linux / Unix, и такие проблемы могут быстро всплыть

0 голосов
/ 10 января 2009

Может быть, это сокет какого-то другого протокола («Не могу определить протокол», а?), Который используется внутри реализации для выполнения чего-то, что создается на первом сокете.

Вы пытались многократно создавать сокеты и закрывать их, чтобы увидеть, действительно ли эти сокеты сохраняются? Кажется вероятным, что это единовременно.

Java, вероятно, использует сокеты для многих целей - это могут быть Unix, Netlink (под Linux) или сокеты другого типа.

...