Подтвердить что ты не робот

Процесс Java на Mac OSX не освобождает сокет

Я испытываю странную проблему время от времени (слишком часто на самом деле).

Я запускаю серверное приложение, которое связывает сокет для себя.

Но время от времени сокет не освобождается. Процесс замирает, хотя 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)

Проблема в худшем случае в моих модульных тестах, которые никогда не выполняются полностью, потому что это обязательно произойдет после одного из тестов (которые все воссоздают сервер).

Я запускаю MacOSX 10.7.3

Java (TM) SE Runtime Environment (сборка 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. Я получил "Terminate failed", но 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:

? E в выводе ps выше означает, что процесс завершается. Я не мог найти никаких средств для полного уничтожения такого процесса без перезагрузки. Эта же проблема была замечена в некоторых других приложениях. Решение не найдено:

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

4b9b3361

Ответ 1

Таким образом, кажется, что проблема заключается в реализации Selector в версии JDK для Mac 6. Установка нового Oracle JDK 7u4 устраняет проблему независимо от того, как используется селектор.

Ответ 3

Просто сделайте снимок в темноте, но убедитесь, что любой поток, ожидающий Selector.select(), проснулся и вышел.

Ответ 4

У меня также есть Parallels, и часто проблема выглядит так, как это вызвано сетевым адаптером Parallels....

Я бы сказал, что справедливая ставка, если эта проблема не возникает на других платформах. Что вы сделали, чтобы исключить Parallels в качестве виновника?

Ответ 5

если вы считаете, что ресурсы не выпущены должным образом, вы можете попытаться сделать выпуск в shutdownhook. как это, по крайней мере, когда его закрытие будет выпущено (не будет, если вы тяжело убиваете)

пример для очень простого shutdownhook:

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

Это помогло мне освободить ресурсы, которые раньше не были полностью выпущены. Я не знаю, работает ли это для сокетов, я думаю, что это должно быть.

Это также позволило мне увидеть записи, которые я раньше не видел