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

Сбор мусора в .NET(поколения)

Я прочитал много статей о производительности .NET, которые описывают Gen1, сборку мусора Gen2 и объекты, переживающие поколения.

Почему предметы выживают в коллекции?

Что такое пиннинг?

4b9b3361

Ответ 1

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

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

Когда объект выживает в коллекции, он переносится в более долгоживущее поколение на теорию о том, что, если он выжил в одной коллекции, он, вероятно, выживет другими. Таким образом, более поздние поколения имеют меньше оборотов и не фрагментируют столько же. Это означает, что ваша программа тратит меньше времени на общее жонглирование вокруг, чтобы очистить дыры и избавить от потери памяти. Это также является улучшением по сравнению с традиционным управлением памятью (malloc/free или new/delete), что оставило его до операционной системы для управления фрагментацией памяти.

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

Иногда люди испытывают соблазн называть GC.Collect() в попытке заставить сборщика мусора очистить что-то. Возможно, они обнаружили, что у них есть утечка, или думают, что память становится чрезмерно фрагментированной. Вы должны противостоять этим побуждениям. Хотя сборка мусора в .Net не идеальна, это очень хорошо, и это почти наверняка намного лучше при очистке памяти, чем вы. Коэффициенты заключаются в том, что если объект может и должен быть собран, он будет. Помните, что вызов GC.Collect() может на самом деле ухудшить ситуацию, помогая сборщику мусора перемещать объекты до более высокого поколения и тем самым поддерживать их дольше, чем они были бы в противном случае.

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

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

Ответ 2

http://blogs.msdn.com/maoni/ - хороший ресурс.
Задаваемые здесь вопросы также помогают:)

По всем вопросам:

Почему объекты выживают из коллекции:
Объекты выживают из коллекции, когда они являются "живыми объектами" или "Доступными объектами". Достижимые объекты - это объекты, где есть ссылка на них из другого объекта, который находится:

  • Стек
  • Очередь финализации
  • другой объект в более высоком поколении (например, объект Gen2, содержащий ссылку на объект Gen0)
  • Таблица дескрипторов (структура данных, используемая CLR, и требует отдельную запись самостоятельно).

Что пиннинг:
 Привязка означает, что объект не перемещается в памяти. объекты перемещаются в памяти в результате уплотнения GC, вы можете создать GCHandle типизированного, закрепленного, если вы хотите привязать объект, и фиксация также происходит автоматически позади sciene для объектов, которые передаются в собственный код через PInvoke (например, строки, которые передается в качестве вывода, внутренний буфер зажимается во время вызова PInvoke).

Посмотрите http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.aspx для хорошего примера о GCHandle.

Ответ 6

Это - интересная статья по теме, которая может показаться информативной.

Ответ 7

Привязка используется, чтобы убрать сборщик мусора от перемещения объектов. Это может повредить производительность, ограничив то, что может сделать сборщик мусора. В общем, закрепленные объекты должны быть закреплены как можно короче.