12

私は時々奇妙な問題を経験しています(実際にはあまりにも頻繁に)。

自分自身のソケットをバインドしているサーバーアプリケーションを実行しています。

しかし、時々、ソケットは解放されません。EclipseはTerminateが失敗したと報告しますが、プロセスは終了しますが、「ps」およびJConsole/JVisualVMから適切に消えます。'lsof'は、ポートに対しても何も表示しなくなりました。それでも、同じポートでサーバーを再起動しようとすると、このエラーが発生します。

Caused by: java.net.BindException: Address already in use
    at sun.nio.ch.Net.bind(Native Method)
    at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:126)
    at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:59)

この問題は、完全に実行されることのない単体テストで最悪です。これは、テストの1つ(すべてサーバーを再作成する)の後に確実に発生するためです。

MacOSX10.7.3を実行しています

Java(TM)SEランタイム環境(ビルド1.6.0_31-b04-415-11M3635)Java HotSpot(TM)64ビットサーバーVM(ビルド20.6-b01-415、混合モード)

私もParallelsを持っており、Parallelsネットワークアダプタが原因で問題が発生しているように見えることがよくありますが、結局この問題と関係があるかどうかはわかりません(これまでのところ何の助けもなしにサポートに連絡しました)。

この状況を解決するのに役立つ唯一のことは、OSXを再起動することです。

何か案は?

-

これは、ソケットを開くための関連コードです。

channel = (ServerSocketChannel) ServerSocketChannel.open().configureBlocking(false);
 channel.socket().bind( addr, 0 );

そしてそれはによって閉じられます

  channel.close();

しかし、プロセスがここでスタックし、Eclipseがそれを強制終了すると思います。

-

netstat -an(ポート6007の場合):

tcp4      73      0  127.0.0.1.6007         127.0.0.1.51549        ESTABLISHED
tcp4       0      0  127.0.0.1.51549        127.0.0.1.6007         ESTABLISHED
tcp4      73      0  127.0.0.1.6007         127.0.0.1.51544        CLOSE_WAIT 
tcp4       0      0  127.0.0.1.6007         127.0.0.1.51543        CLOSE_WAIT 
tcp4       0      0  10.37.129.2.6007       *.*                    LISTEN     
tcp4       0      0  10.211.55.2.6007       *.*                    LISTEN     
tcp4       0      0  127.0.0.1.6007         *.*                    LISTEN     
tcp4       0      0  10.50.100.236.6007     *.*                    LISTEN     

-

そして今、すべてのテストでソケットが開かれた後、この例外が発生します(この状況からのnetstat出力):

Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:129)
    at java.net.SocketInputStream.read(SocketInputStream.java:182)

-

Eclipseからプロセスを停止すると、「終了に失敗しました」というメッセージが表示されますが、lsof -i TCP:6007は何も表示せず、プロセスは「ps」によって検出されなくなります。netstatの出力は変更されませんでした...

再起動せずにどういうわけかソケットを強制終了できますか(それはすでに少し助けになります)?

-

アップデート5.5.12:

Eclipseデバッガーでテストを実行しました。今回は、18のメソッドの後でテストがスタックしました。メインスレッドが15分ほどスタックした後、メインスレッドを停止しました。これはスタックです:

Thread [main] (Suspended)   
    FileDispatcher.preClose0(FileDescriptor) line: not available [native method]    
    SocketDispatcher.preClose(FileDescriptor) line: 41  
    ServerSocketChannelImpl.implCloseSelectableChannel() line: 208 [local variables unavailable]    
    ServerSocketChannelImpl(AbstractSelectableChannel).implCloseChannel() line: 201 
    ServerSocketChannelImpl(AbstractInterruptibleChannel).close() line: 97  
...

-

うーん、結局のところ、プロセスは強制終了されていないようです-そして-9を強制終了するために死ぬこともありません(プロセス712とおそらく710もTestNGプロセスであることに気づきました):

$ kill -9 712
$ ps xa | grep java
  700   ??  ?E     0:00.00 (java)
  712   ??  ?E     0:00.00 (java)
  797 s005  S+     0:00.00 grep java

-編集:10.5.12:

上記のps出力の?Eは、プロセスが終了していることを意味します。再起動せずにそのようなプロセスを完全に強制終了する手段を見つけることができませんでした。同じ問題が他のいくつかのアプリケーションでも見られます。解決策が見つかりません:

http://www.google.com/search?q=ps+process+is+exiting+osx

4

5 に答える 5

3

ここでは暗闇の中でのショットですが、Selector.select() で待機しているスレッドが起動され、終了していることを確認してください。

于 2012-05-14T19:07:21.433 に答える
3

まだ行っていない場合は、各テストの後、ティアダウンでhttp://docs.oracle.com/javase/1.4.2/docs/api/java/net/ServerSocket.html#close ()でソケットを閉じてみて ください。 .

于 2012-05-04T15:35:26.217 に答える
2

したがって、問題はMacバージョンのJDK6でのSelectorの実装にあるようです。新しいOracleJDK7u4をインストールすると、Selectorの使用方法に関係なく、問題が修正されます。

于 2012-05-24T15:24:30.243 に答える
0

私は Parallels も持っていますが、多くの場合、問題は Parallels ネットワーク アダプターが原因のように見えます....

この問題が他のプラットフォームで発生していない場合、それは公正な賭けだと思います. Parallels を犯人から除外するために何をしましたか?

于 2012-05-10T06:17:32.143 に答える
0

リソースが適切に解放されていないと思われる場合は、shutdownhook で解放を試みることができます。このように、少なくともシャットダウンすると、リソースが解放されます(ただし、強制終了した場合はそうではありません)

非常に基本的なシャットダウンフックの例:

public void shutDownProceedure(){
    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            /* my shutdown code here */
        }
    });
}

これにより、以前は完全にリリースされていなかったリソースをリリースすることができました。これがソケットでも機能するかどうかはわかりませんが、そうすべきだと思います。

また、これまでに見たことのないログを見ることもできました

于 2012-05-10T19:49:30.860 に答える