Этот ответ начался как комментарий для Мика , который утверждает, что :
Это зависит от того, с какой версией .NET вы работаете.На мобильных платформах, таких как Xamarin или mono, вы можете обнаружить, что сборщик мусора нуждается в такой помощи для выполнения своей работы.
Это утверждение требует проверки фактом.Итак, давайте посмотрим ...
.NET
.NET использует марку поколения и сборщик мусора.Вы можете увидеть реферат алгоритма в Что происходит во время сборки мусора .Для краткости, он проходит по графу объектов, и если он не может достичь объекта, его можно удалить.
Таким образом, сборщик мусора будет правильно идентифицировать элементы списка как коллекционные вта же самая итерация , независимо от того, очистите ли вы список или нет.Нет необходимости предварительно разъединять объекты.
Это означает, что очистка списка не помогает сборщику мусора при обычной реализации .NET.
Примечание :Если бы была еще одна ссылка на список, то тот факт, что вы очистили список, будет виден.
Моно и Xamarin
Моно
Как оказалось, то же самое верно для Моно .
Xamarin.Android
Также верно для Xamarin.Android.
Xamarin.iOS
Однако Xamarin.iOS требует дополнительных соображений.В частности, MonoTouch будет использовать обернутые объекты Objective-C , которые находятся за пределами сборщика мусора.См. Избегайте сильных циклических ссылок в iOS Performance .Эти объекты требуют различной семантики.
Xamarin.iOS минимизирует использование объектов Objetive-C, сохраняя кэш:
C # NSObjects также создаются по требованию при вызове методаили свойство, которое возвращает объект NSObject.На этом этапе среда выполнения изучит кэш объектов и определит, был ли данный объект NSO Objective C уже представлен в управляемом мире или нет.Если объект был обнаружен, будет возвращен существующий объект, в противном случае для создания объекта вызывается конструктор, который принимает IntPtr в качестве параметра.
Система поддерживает эти объекты живыми, даже если их нетссылки из управляемого кода:
Пользовательские подклассы объектов NSO часто содержат состояние C #, поэтому всякий раз, когда среда выполнения Objective C выполняет операцию " retain " над одним из этих объектов, среда выполнениясоздает GCHandle, который поддерживает управляемый объект, даже если в C # нет видимых ссылок на объект .Это значительно упрощает буперинг, так как состояние будет сохраняться автоматически для вас.
Выделение мое.
Таким образом, в Xamarin.iOS, если быливероятность того, что список может содержать обернутые объекты Objetive-C, этот код поможет сборщику мусора.
См. вопрос Как работает управление памятью в Xamarin.IOS , Miguelде Икаса объясняет в своем ответе , что семантика состоит в том, чтобы " сохранить " объект, когда вы берете ссылку, и " release ", когда ссылка нулевая.
На стороне Objetive-C «выпуск» не означает уничтожение объекта.Objetive-C использует сборщик мусора для подсчета ссылок.Когда мы " сохраняем " объект, счетчик увеличивается, а когда мы " отпускаем ", счетчик уменьшается.Система уничтожает объект, когда счетчик достигает нуля.См .: Об управлении памятью .
Следовательно, Objetive-C плохо обрабатывает циклические ссылки (если A
ссылки B
и B
ссылки A
, их число ссылок не равно нулю, даже если они не могут быть достигнуты), таким образом, выследует избегать их в Xamarin.iOS.На самом деле, если вы забудете отделить ссылки, это приведет к утечкам в Xamarin.iOS ... См .: Утечки памяти Xamarin iOS везде .
Другие
dotGNU такжеиспользует метку поколения и сборщик мусора.
Я также взглянул на CrossNet (который компилирует IL в C ++), похоже, они тоже пытались реализовать его.Я не знаю, как это хорошо.