Есть ли утечка файлового дескриптора при использовании сокетов на платформе Linux?

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

Вопрос

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

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?

Это было полезно?

Решение

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

Другие советы

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top