Я прочитал много статей о производительности .NET, которые описывают Gen1, сборку мусора Gen2 и объекты, переживающие поколения.
Почему предметы выживают в коллекции?
Что такое пиннинг?
Я прочитал много статей о производительности .NET, которые описывают Gen1, сборку мусора Gen2 и объекты, переживающие поколения.
Почему предметы выживают в коллекции?
Что такое пиннинг?
Одна из причин, по которой у вас есть несколько поколений в сборщике мусора, заключается в том, чтобы избежать потери памяти для фрагментации.
Каждый вызов функции может означать создание и удаление коллекции нескольких объектов, и поэтому куча памяти для вашей программы имеет тенденцию фрагментироваться очень быстро. Это оставляет дыры позади, которые не очень полезны. В результате ваша программа должна быть периодически дефрагментирована, как жесткий диск. Это часть того, что происходит во время сбора.
Когда объект выживает в коллекции, он переносится в более долгоживущее поколение на теорию о том, что, если он выжил в одной коллекции, он, вероятно, выживет другими. Таким образом, более поздние поколения имеют меньше оборотов и не фрагментируют столько же. Это означает, что ваша программа тратит меньше времени на общее жонглирование вокруг, чтобы очистить дыры и избавить от потери памяти. Это также является улучшением по сравнению с традиционным управлением памятью (malloc/free или new/delete), что оставило его до операционной системы для управления фрагментацией памяти.
Причина, по которой объект выживает, состоит в том, что есть что-то где-то, что по-прежнему "в области видимости" и содержит ссылку на этот объект. Есть несколько способов заставить это произойти, а затем забыть о ссылке, поэтому возможно "утечка" памяти в управляемом коде.
Иногда люди испытывают соблазн называть GC.Collect()
в попытке заставить сборщика мусора очистить что-то. Возможно, они обнаружили, что у них есть утечка, или думают, что память становится чрезмерно фрагментированной. Вы должны противостоять этим побуждениям. Хотя сборка мусора в .Net не идеальна, это очень хорошо, и это почти наверняка намного лучше при очистке памяти, чем вы. Коэффициенты заключаются в том, что если объект может и должен быть собран, он будет. Помните, что вызов GC.Collect()
может на самом деле ухудшить ситуацию, помогая сборщику мусора перемещать объекты до более высокого поколения и тем самым поддерживать их дольше, чем они были бы в противном случае.
Вместо этого, если вы подозреваете, что у вас есть утечка, посмотрите на свой собственный код для чего-то вроде глобальной или статической переменной, которая может содержать ссылку на множество других элементов. Единственный раз, когда вы должны позвонить GC.Collect()
, - это когда у вас есть информация о характере программы, недоступной сборщику мусора, и это довольно редко, так как GC знает каждую созданную вами ссылку.
"Привязка" - это когда вам нужно передать объект в неуправляемую библиотеку. Сборщик мусора может перемещать физическое местоположение объекта в памяти, и поэтому вам нужно "привязать" его в одном месте или указатель, используемый неуправляемой библиотекой, может стать недействительным. Закрепленный объект не может быть собран, поэтому вы не должны привязывать объект дольше, чем необходимо.
http://blogs.msdn.com/maoni/ - хороший ресурс.
Задаваемые здесь вопросы также помогают:)
По всем вопросам:
Почему объекты выживают из коллекции:
Объекты выживают из коллекции, когда они являются "живыми объектами" или "Доступными объектами". Достижимые объекты - это объекты, где есть ссылка на них из другого объекта, который находится:
Что пиннинг:
Привязка означает, что объект не перемещается в памяти. объекты перемещаются в памяти в результате уплотнения GC, вы можете создать GCHandle типизированного, закрепленного, если вы хотите привязать объект, и фиксация также происходит автоматически позади sciene для объектов, которые передаются в собственный код через PInvoke (например, строки, которые передается в качестве вывода, внутренний буфер зажимается во время вызова PInvoke).
Посмотрите http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.aspx для хорошего примера о GCHandle.
Вот короткая, но полная программа, которую я написал для демонстрации коллекции мусора gen 2 в запущенном приложении
http://nomorehacks.wordpress.com/2008/11/27/forcing-the-garbage-collector/
Я думал, что эта статья тоже была неплохой.
http://msdn.microsoft.com/en-us/library/ms973837.aspx
Очень большая тема. Выше - хорошее резюме от MS.
Это - интересная статья по теме, которая может показаться информативной.
Привязка используется, чтобы убрать сборщик мусора от перемещения объектов. Это может повредить производительность, ограничив то, что может сделать сборщик мусора. В общем, закрепленные объекты должны быть закреплены как можно короче.