Последствия неиспользования () подключений к БД?

Использование "использования" в C# имеет хорошее объяснение утилит using особенность.

.Net имеет свой сборщик мусора. Как это справляется с отсутствием дипозы ()?

Специально для соединений с БД, операторов и наборов результатов требуется ли использование () для каждого из них? Что произойдет, если их оставить без использования (), dispose() и не закрыть ()?

Обновление: контекст - это веб-приложения, поэтому одновременно могут быть тысячи пользователей, каждый со своим собственным подключением /stmt/rs, и приложение никогда не будет закрыто.

4 ответа

Решение

Специально для соединений с БД, операторов и наборов результатов требуется ли использование () для каждого из них? Что произойдет, если их оставить без использования (), dispose() и не закрыть ()?

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

Если увеличение памяти возрастает до уровня, при котором GC больше не может выполнять очистку, фактически, если Gen 2 из кучи малых объектов переполнен (куча больших объектов также может переполниться), он выкинет исключение из памяти и закроет приложение.

.Net имеет свой сборщик мусора. Как это справляется с отсутствием дипозы ()?

Все стандартные классы, связанные с подключением к базе данных, правильно реализовали методы Dispose и Finalize. Обычно в этих классах есть неуправляемые ресурсы. Неуправляемые ресурсы - это ресурсы (например, обработчики файлов, обработчики подключений к базам данных и т. Д.), Которые могут привести к более серьезным утечкам памяти, которые могут удерживать память до перезагрузки компьютера. Тем не менее, вот где GC завершает работу. Если вы не вызываете Dispose для такого объекта Disposable, сборщик мусора выполнит метод Finalize (если есть деструктор) и очистит неуправляемые ресурсы.

По этой причине требуется правильно реализовать шаблон IDispose. Dispose и Finalization по мере необходимости. Финализация требуется только в том случае, если у нее есть неуправляемые ресурсы.

Поскольку using это сокращение для звонка DisposeВы можете имитировать это с помощью try/finally. Таким образом, реальный вопрос заключается в том, что является следствием не звонить Dispose совсем.

Хотя C# имеет сборку мусора, которая в конечном итоге будет высвобождать ресурсы большую часть времени, вы хотите, чтобы выпуск критических ресурсов происходил, как только вы закончили с ними. Если вы используете using или эквивалент try/finally, ресурсы будут выпущены быстро. Если вы позволите сборщику мусора освободить ресурсы для вас, ваша программа может испытывать нехватку ресурсов, пока они "находятся под стражей" GC (т.е. ваша программа больше не использует их, но GC еще не выпустила их). Более того, поскольку GC не дает жесткой гарантии запуска финализаторов, некоторые ресурсы могут не освобождаться явно до тех пор, пока ваша программа не завершится, что может привести к нехватке ресурсов других процессов.

Вы не знаете, когда вызывается и запускается сборщик мусора.net, поэтому он позволяет вам делать это самостоятельно, когда вам это не нужно. Таким образом, когда ваш код выходит из использования (), он удаляет объект, используемый в использовании (), вместо того, чтобы ждать запуска GC по собственному расписанию.

Если вы не используете соединение с БД, то GC будет распоряжаться им по-своему, основываясь на критериях реализуемого алгоритма. Это может быть слишком поздно (с точки зрения компьютерных часов), чтобы подмести его.

Сборщик мусора - это фоновый поток, который запускается не каждую миллисекунду. У этого есть определенное расписание и его собственный алгоритм, который стремится это работать в определенное время. Например, некоторые алгоритмы GC проверяют наличие объектов, не имеющих ссылок, а затем сканируют эти объекты при запуске GC.

Наиболее вероятное последствие неудачной попытки Dispose Объекты базы данных состоят в том, что программа попросит сервер базы данных открыть соединения с базой данных от своего имени с обещанием, что она сообщит серверу, когда они больше не нужны (т.е. закроют их), но может оставить соединения открытыми на некоторое время после они больше не нужны. Такое поведение может увеличить количество соединений, которые серверу базы данных необходимо будет поддерживать открытыми одновременно. В зависимости от сервера, это может не иметь последствий, или дополнительные соединения могут ухудшить производительность, или они могут вызвать ненужное отклонение некоторых запросов на соединение.

Хотя.NET будет пытаться гарантировать, что серверы баз данных будут получать уведомления, когда объекты базы данных будут оставлены, даже если Dispose не вызывается, код, который использует объекты базы данных, как правило, будет знать, когда он им больше не понадобится, задолго до того, как.NET сможет определить, что они заброшены Также обратите внимание, что хотя некоторые библиотеки, связанные с базой данных.NET, могут сохранять соединения открытыми некоторое время после Dispose (так что, если код снова нуждается в базе данных, он может возобновить использование более раннего соединения), такие библиотеки могут использовать таймеры для ограничения продолжительности поддерживаемых соединений в ожидании дальнейшего использования, а не зависеть от сборщика мусора (который может продолжаться очень долго время, не замечая, что объект был заброшен).

Другие вопросы по тегам