2011-08-12 12 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によりファイル記述子のリークが発生する

ただし、ファイルディスクリプタはリークし、すべてがUNIXドメインソケットです。

"netstat -anp"コマンドを使用すると、プロセスが2つのunixドメインソケットのみを開くことがわかります。 しかし、lsof -pを使用すると、unixドメインソケットであり、netstatで見つけられたのと同じデバイス値とノード値を持つ膨大な量のファイル記述子があることがわかります。

私はコードをチェックしており、すべてのSocketChannelが正しく閉じられています。

Sun JDKのバグですか? どうすれば修正できますか?

+0

Java 6アップデート26を試しましたか? JVMバグの場合、バグであることを示すように修正されている可能性があります。 –

+0

@James UnixドメインソケットでJavaを使用するNIO APIはどれですか? XNIOのような特定のAPIを使用していますか?私はUnix Domain SocketsとNIOで動作するものを探しています。ありがとう。 – jbx

答えて

2

根本原因が見つかりました。 私たちのコードでは、socketchannelを閉じると、キーもキャンセルされます。問題は次のとおりです。 a。 selectスレッドのキーをキャンセルし、別のスレッドのsocketchannelを閉じます。 b。ソケットチャネルは、key.cancelが呼び出されるまで閉じられます。

closeとcancelの実装を読むことで、unixドメインソケットがdup2によって開かれ、何度か閉じられてしまうことはない(同時の問題)ことがわかります。

+0

チャンネルを閉じると、キーがキャンセルされます。キャンセルする必要はありません。 key.cancelが呼び出されるまでソケットのチャンネルが閉じられているのは分かりません。実際に何が起こるかは、チャンネルがセレクタが次に実行されるまで実際には閉じられていないということです。 – EJP

+0

セレクタスレッド以外のスレッドで次のコードを実行すると、問題が発生します。 'selectionKey.cancel(); socketChannel.close(); ' コードでは少し異なります。 selectionKey.cancelはセレクタスレッドで呼び出され、別のスレッドに 'socketChannel.close();'を呼び出すように通知します。キーは実際に次の選択時にキャンセルされるため、同時に問題が発生します。 – James

+0

こんにちはEJP、私たちが遭遇した問題は、次回セレクタが実行されても、同時に発生する問題のためにUnixドメインソケットが閉じられないということです。実際、UNIXドメインソケットは、同時の問題が発生した場合に閉じられる機会はありません。 – James

0

私はSelectorsがUnixドメインソケットを使用していると信じています。あなたはそれらを閉じていますか?

+0

Selectorインスタンスを1つだけ作成し、決して閉じません。 – James

関連する問題