2011-08-12 2 views
2

우리는 Java NIO를 기반으로 구현 된 http 서버를 가지고 있습니다. Java 버전 "1.6.0_20"을 사용하는 Ubuntu 10.04.2 LTS에서 실행 중임 Java (TM) SE 런타임 환경 (빌드 1.6.0_20-b02) Java HotSpot (TM) 서버 VM (빌드 16.3-b01, 혼합 모드)Java NIO가 파일 설명자를 유출시킵니다.

그러나 파일 설명자를 유출합니다. 모두 유닉스 도메인 소켓입니다.

"netstat -anp"명령을 사용하면 프로세스가 두 개의 unix 도메인 소켓 만 열 수 있음을 알 수 있습니다. 그러나 lsof -p를 사용하면 유닉스 도메인 소켓이며 netstat에서 찾은 것과 동일한 장치 값과 노드 값을 가진 막대한 양의 파일 디스크립터가 있음을 알 수 있습니다.

코드를 확인했으며 모든 SocketChannels이 제대로 닫혔습니다.

Sun JDK의 버그입니까? 어떻게 해결할 수 있습니까?

+0

Java 6 업데이트 26을 사용해 보셨습니까? JVM 버그 인 경우, 그것이 버그 인 것으로 판명되었을 가능성이 있습니다. –

+0

@James 유닉스 도메인 소켓에서 자바를 사용하기 위해 어떤 NIO API를 사용하고 있습니까? XNIO와 같은 특정 API를 사용하고 있습니까? Unix Domain Sockets 및 NIO에서 작동하는 것을 찾고 있습니다. 감사. – jbx

답변

2

근본 원인이 발견되었습니다. 코드에서 socketchannel을 닫으면 키도 취소됩니다. 문제는 다음과 같습니다. a. 선택 스레드에서 키를 취소하고 다른 스레드의 소켓 채널을 닫습니다. b. 소켓 채널은 key.cancel이 호출 될 때까지 닫힙니다.

닫기 및 취소의 구현을 읽으면 unix 도메인 소켓이 dup2에 의해 열리고 절대로 몇 번 닫히지 않을 수 있음을 발견했습니다 (동시 문제).

+0

채널을 닫으면 키가 취소됩니다. 직접 취소 할 필요가 없습니다. key.cancel이 호출 될 때까지 소켓 채널이 닫힌다는 것을 알지 못합니다. 실제로 일어나는 일은 채널이 다음에 선택기가 실행될 때까지 실제로 닫히지 않습니다 *입니다. – EJP

+0

다음 코드가 선택기 스레드가 아닌 스레드에서 실행되는 경우 문제가 발생합니다. 'selectionKey.cancel(); socketChannel.close(); ' 코드에서는 약간 다릅니다. selectionKey.cancel은 셀렉터 쓰레드에서 호출되며, 다른 쓰레드에게'socketChannel.close(); '를 호출하도록 알립니다. 키가 실제로 다음 선택시 취소되므로 동시 발행 문제가 있습니다. – James

+0

안녕 EJP, 우리가 만난 문제는 다음 번에 셀렉터가 실행될 때조차도 동시 문제로 인해 유닉스 도메인 소켓이 닫히지 않는다는 것입니다. 실제로, 동시 문제가 발생하면 유닉스 도메인 소켓은 닫힐 기회가 없습니다. – James

0

저는 Selectors가 Unix 도메인 소켓을 사용한다고 생각합니다. 그들을 폐쇄하고 있습니까?

+0

Selector 인스턴스를 하나만 만들고 절대로 닫지 않습니다. – James

관련 문제