Mac OSX上的Java进程不会释放套接字

Jou*_*Aro 12 java eclipse macos parallels

我经常遇到一个奇怪的问题(实际上经常).

我正在运行一个服务器应用程序,它为自己绑定一个套接字.

但有一段时间,套接字没有被释放.虽然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)
Run Code Online (Sandbox Code Playgroud)

这个问题在我的单元测试中是最糟糕的,它永远不会完全运行,因为这肯定会在其中一个测试(所有重新创建服务器)之后发生.

我正在运行MacOSX 10.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 );
Run Code Online (Sandbox Code Playgroud)

它被关闭了

  channel.close();
Run Code Online (Sandbox Code Playgroud)

但我认为这个过程在这里被卡住了,然后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     
Run Code Online (Sandbox Code Playgroud)

-

现在,在为每个测试打开套接字后,我得到此异常(此情况下的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)
Run Code Online (Sandbox Code Playgroud)

-

从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  
...
Run Code Online (Sandbox Code Playgroud)

-

嗯,毕竟看起来这个过程并没有被杀死 - 并且也不会死于杀死-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
Run Code Online (Sandbox Code Playgroud)

- 编辑:10.5.12:

?上面的ps输出中的E表示该进程正在退出.我找不到任何方法可以在不重新启动的情况下完全杀死这样一个进程.其他一些应用程序也注意到了同样的问题.找不到解决方案:

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

Jou*_*Aro 2

因此,问题似乎出在 Mac 版本 JDK 6 中 Selector 的实现。安装新的 Oracle JDK 7u4 修复了该问题,与 Selector 的使用方式无关。