Нужно ли явно закрывать SocketChannel при завершении работы приложения?

Скажем, у нас есть открытый SocketChannel. Важно ли явно закрывать его перед завершением работы приложения? Другими словами, если мы этого не сделаем, есть ли риск оставить незакрытыми системные ресурсы?


person Andremoniy    schedule 12.09.2018    source источник
comment
хорошо, когда вы вызываете close, он также закрывает Socket, и я думаю, что это то, что вам может понадобиться   -  person Eugene    schedule 12.09.2018
comment
Вы, вероятно, не создадите утечку ресурсов, поскольку уничтожение JVM все равно освободит сокет. Но результаты могут отличаться с другой стороны - например, прерывание потока или закрытие потока.   -  person Antoniossss    schedule 12.09.2018


Ответы (2)


Предполагая, что ваша ОС является современной многопользовательской операционной системой, нет риска, что выход из процесса без закрытия каналов, докетов, файловых дескрипторов оставит ресурсы незакрытыми. Все ресурсы, принадлежащие процессу пользовательского пространства, обрабатываются ОС надлежащим образом (т. е. при необходимости закрываются1) при завершении процесса.

Это применимо, когда пользовательский процесс представляет собой JVM, выполняющую приложение Java, а также к любому другому пользовательскому процессу.


1 - Это немного сложнее, чем "все закрыто". Например, в UNIX/Linux дочерний процесс может наследовать дескрипторы открытых «файлов» от своего родителя, поэтому вполне возможно, что два или более пользовательских процесса могут совместно использовать сетевой сокет. ОС обработает этот сценарий с помощью подсчета ссылок.

person Stephen C    schedule 12.09.2018

Сокет автоматически закроется, когда ваш процесс завершится, и все ресурсы процесса будут освобождены.

НО, если это сокет TCP, то другой конец обычно не будет уведомлен, когда это произойдет. Это будет так же, как если бы кто-то отключил сетевой кабель.

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

Если вы хотите создать процесс и заставить его умереть, когда родитель выйдет из строя, я предлагаю использовать для этого безымянный канал к дочернему процессу stdin. Это самое простое и очень надежное.

person Matt Timmermans    schedule 13.09.2018
comment
TCP действительно уведомляет одноранговый узел, по крайней мере, в операционных системах, где работает JavaSE: если какой-либо процесс, включая JVM, просто завершается, Unix отправляет FIN (например, shutdown()), если вы не установили Linger, тогда он отправляет RST; Windows отправляет RST. Для смарткарты или чего-то подобного, может и нет. - person dave_thompson_085; 13.09.2018
comment
Это не было моим опытом для внезапно завершенных процессов, особенно в Windows. У вас есть реф? Я все еще не очень верю в это, но это может помочь ОП принять решение :-) - person Matt Timmermans; 13.09.2018
comment
Я почти уверен, что видел какую-то спецификацию Unix по этому вопросу, но давно назад, и сейчас я не могу найти подходящей; Я не думаю, что когда-либо даже искал спецификацию MS, просто заметил, что она отличается, и подумал, как обычно. Но я выполнял этот случай тысячи раз в течение многих лет, некоторые преднамеренно (тестирование логики обработки ошибок) и многие непреднамеренно (что-то умерло из-за ошибки, и другой код или скаффолдинг увидел это). Хотя и не на W10 (я это отвергаю), и, возможно, это могло бы отличаться. Не стесняйтесь получить tcpdump или wireshark или что-то еще, что применимо, и попробуйте. - person dave_thompson_085; 14.09.2018