Будет ли сборщик мусора вызывать IDisposable.Dispose вместо меня?

Я хочу подчеркнуть точку dotnet зрения Брайана в его комментарии, потому idisposable что это важно.

Финализаторы dot-net не являются детерминированными idisposable деструкторами, как в C++. Как resource-disposal указывали другие, нет никакой dotnet гарантии, когда он будет dotnet вызван, и действительно, если idisposable у вас достаточно памяти, если dispose он будет когда-либо вызываться.

Но плохая disposing сторона финализаторов заключается dispose в том, что, как сказал Брайан, ваш .net объект выживает при сборке disposing мусора. Это может быть плохо. Почему?

Возможно, вы dotnet знаете или не знаете, GC idisposable разделен на поколения — Gen dot-net 0, 1 и 2, плюс куча больших .net-framework объектов. Разделение — это dot-net расплывчатый термин — вы disposal получаете один блок памяти, но disposal есть указатели на то, где disposing начинаются и заканчиваются dotnet объекты Gen 0.

Мысль заключается idisposable в том, что вы, вероятно, будете .net использовать множество объектов, которые idisposable будут недолговечны. Таким dispose образом, сборщик мусора должен disposing легко и быстро добраться dispose до объектов Gen 0. Поэтому, когда disposal возникает нехватка памяти, первое, что idisposable он делает, — это коллекция dotnet Gen 0.

Теперь, если это не idisposable устраняет достаточное давление, он disposing возвращается и выполняет idisposable развертку поколения 1 (повторяя resource-disposal поколение 0), а затем, если dot-net все еще недостаточно, выполняет .net-framework развертку поколения 2 (повторно idisposable выполняя поколение 1 и поколение .net-framework 0). Таким образом, очистка .net-framework долгоживущих объектов может idisposable занять некоторое время и idisposable быть довольно дорогой (поскольку disposing ваши потоки могут быть приостановлены disposal во время операции).

Это означает, что dot-net если вы сделаете что-то вроде .net-framework этого:

~MyClass() { }

Ваш объект, несмотря disposing ни на что, будет жить до dot-net поколения 2. Это потому, что .net GC не может вызвать финализатор dispose во время сборки мусора. Таким .net-framework образом, объекты, которые disposal должны быть завершены, перемещаются .net-framework в специальную очередь для .net очистки другим потоком (поток dot-net финализатора, который, если idisposable вы его убьете, приведет к dotnet всевозможным плохим вещам). Это .net означает, что ваши объекты disposal задерживаются дольше и потенциально dotnet вызывают больше сборок мусора.

Итак, все resource-disposal это просто для того, чтобы dot-net понять, что вы хотите использовать dispose IDisposable для очистки ресурсов, когда dispose-pattern это возможно, и серьезно resource-disposal попытаться найти способы dotnet обхода финализатора. Это idisposable в интересах вашего приложения.

.net

dispose

idisposable

2022-09-24T04:07:45+00:00