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 가이 소켓을 재사용하기 위해이 소켓을 재사용해야합니까?

도움이 되었습니까?

해결책

해당 소켓이 모두 Time_wait 상태에 있으면 적어도 잠시 동안 정상입니다. Netstat로 확인하십시오. 새 소켓을 위해 포트를 재사용하기 전에 소켓에서 깎아내는 데이터가 성공적으로 버려 지도록 소켓이 몇 분 동안 매달려있는 것이 일반적입니다.

다른 팁

당신은 또한 확인하고 싶을 수도 있습니다 /proc/<pid>/fd, 디렉토리에는 현재 열린 모든 파일 설명자가 포함됩니다. 소켓을 닫은 후 파일이 사라지면 문제가 발생하지 않습니다 (적어도 파일 설명자와 관련이 없습니다 :).

나는 그것이 당신의 프로그램의 문제가 아니라고 생각합니다.

Sun_java에서는 소켓 관련 기본 LIB가로드되면 Magic_Sock FD가 생성됩니다.

Magic_Sock에 쓰기로 인해 Connect REST 예외가 발생하고 Magic_Sock을 읽으면 EOF가 나타납니다.

Magic_Sock의 피어는 완전히 닫혀 있었고 Magic_Sock 자체는 Half_Closed이며 상태는 "프로토콜을 식별 할 수 없습니다".

어쩌면 그것은 다른 프로토콜 ( "프로토콜을 식별 할 수 없음"eh?)의 소켓 일 수 있습니다.

이 소켓이 실제로 지속되는지 확인하기 위해 반복적으로 소켓을 만들고 닫으려고 했습니까? 이것은 일회성 일 것 같습니다.

Java는 아마도 많은 것을 위해 내부적으로 소켓을 사용합니다 - 그들은 Unix, NetLink (Linux) 또는 다른 유형의 소켓 일 수 있습니다.

특정 앱 또는 PID의 열린 소켓을 모니터링하는 작은 bash 스크립트를 만들고 Java 앱을 테스트하는 동안 실행하도록하십시오.

어쨌든 소켓은 Linux/Unix World에서 소켓이 매우 사용되며 이러한 종류의 문제가 매우 빠르게 거품이 될 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top