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

Как работает сборщик мусора и область работы С#?

Я изучаю С# исходящий из python и хочу знать, как работает сборщик мусора С#. Я обнаружил, что я понял намного больше о python, как только выяснил что он делал за кулисами, и хотел бы избежать создания noob-ошибок, которые я сделал сначала, изучая python.

Я не смог найти каких-либо хороших ясных объяснений того, когда элемент собран из мусора, и я оставляю вопросы, такие как

  • "Что происходит с объектом, когда его последняя ссылка выходит за рамки?" Получает ли этот объект сбор мусора или он все еще присутствует, когда вы возвращаетесь в область, в которой он был определен?
  • "В какой момент количество ссылок уменьшается?" Представляя мне задаться вопросом, использует ли он даже подсчет ссылок или какую-то другую технику...

Ответы на эти вопросы или даже лучший отчет о том, что происходит на самом деле, выиграют файлы cookie (или наоборот), и даже лучше, если ваш ответ сравнит его с путинским способом выполнения вещей. Меня не интересует, что лучше, просто детали. Также были бы очень полезны ответы на мой оригинальный пост на programers.stackexchange...

4b9b3361

Ответ 1

DotNet GC двигатель наценки и прогонка двигатель, а не ссылки счетчик двигатель, как вы привыкли в питоне. Система не поддерживает количество ссылок на переменную, а скорее запускает "коллекцию", когда ей необходимо вернуть ОЗУ, пометить все доступные в данный момент указатели и удалить все указатели, которые недоступны (и, следовательно, выходят за рамки).

Вы можете узнать больше о том, как это работает здесь:
http://msdn.microsoft.com/en-us/library/ee787088.aspx

Система находит объекты "достижимые", начиная с определенных "корневых" местоположений, таких как глобальные объекты и объекты в стеке, и отслеживает все объекты, на которые ссылаются те, и все объекты, на которые ссылаются эти и т.д., до тех пор, пока они не построены полное дерево. Это быстрее, чем кажется.

Ответ 2

В какой-то неопределенный момент времени после исчезновения последней ссылки на объект объект будет собран.

Вторая часть вашего первого вопроса не имеет смысла.
Если вы можете вернуться в область, в которой был определен объект (например, лямбда-выражение), очевидно, что есть ссылка.

GC не использует подсчет ссылок вообще.
Скорее, он использует алгоритм mark-and-sweep.

Ответ 3

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

Хороший источник информации о всех подробностях о том, как работает сбор мусора, - это книга Джеффри Рикера CLR через С#. Книга подробно рассказывает о том, как куча разделена и как работает сбор мусора. Очень рекомендуется, если вы заинтересованы в деталях реализации .NET.

Ответ 4

  • Когда объект больше не ссылается на него, ничего не происходит. Каждому объекту присваивается генерация, 0, 1 или 2. Первоначально все объекты помещаются в генерацию 0. Используя алгоритм Mark-and-Sweep, сборщик мусора будет периодически проверять поколение. Если у экземпляра все еще есть сильные ссылки, его повышают до более высокого поколения до 2 (которые обычно проверяются реже). Теория заключается в том, что большинство объектов, как правило, недолговечны, поэтому, если объект прожил достаточно долго, чтобы сделать его поколением 1, его не нужно проверять так часто.
  • В .NET GC отсутствует подсчет ссылок. Скорее он использует отметку и развертку.

Ответ 5

"Сбор мусора" выполняется сборщиком мусора, который является частью среды CLR в .NET.

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

Как работает сборщик мусора

Он периодически смотрит в память, управляет кучей и освобождает память, занятую мертвыми объектами.

мертвый объект идентифицируется, если ваш код недоступен.

Реализация

Существует 3 способа управления памятью: -

GC работает только для управляемых ресурсов, поэтому .NET предоставляет Dispose и Finalize для выпуска неуправляемых ресурсов, таких как поток, подключение к базе данных, COM-объекты и т.д.

1) Уберите

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

Программист должен вызвать это либо с помощью Dispose(), либо с помощью функции

Используйте GC.SuppressFinalize(это), чтобы предотвратить вызов Finalizer, если вы уже использовали dispose()

2) Finalize или Distructor

Он называется неявно после того, как объект имеет право на очистку, финализатор для объектов вызывается последовательно по потоку финализатора.

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

3) GC.Collect()

Использование GC.Collect() не обязательно устанавливает GC для сбора, GC все равно может переопределять и запускать, когда захочет.

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

Используйте WaitForPendingFinalizers, если вы хотите убедиться, что все финализаторы были вызваны после вызова GC.Collect()

Обратитесь к сообщению в моем блоге, где у меня есть эта статья: Коллекция мусора в .NET