Утечки памяти MSIL

Мы используем пользовательский класс RuntimeDataBuilder, который динамически создает тип .NET в памяти с помощью Reflection.Emit для создания простых методов получения/установки свойств для информации, которую мы получаем от универсального WCF DataService. Служба предоставляет структуру типа DataSet, состоящую из 1..m DataTableDefinitions, каждая из которых содержит 1..m DataTableColumnDefinitions. Когда информация получена на стороне клиента, мы генерируем тип с помощью его методов установки/получения свойств, чтобы повысить производительность и упростить привязку к нашему клиенту Silverlight. Все это работает нормально.

Мой вопрос связан с возможной утечкой памяти, связанной с регенерацией типа. Время от времени пользователь может изменять параметры запроса, что может привести к получению большего или меньшего количества информации по сети. Поэтому он делает недействительным предыдущий тип, который мы создали, и я хочу убедиться, что мы можем освободить память, используемую этим предыдущим определением типа. Из этой статьи на MSDN я понял, что если вы используете облегченный код Генерация (LCG) — код размещается в управляемой куче, которая будет утилизирована сборщиком мусора, когда на нее не будет ссылаться ничего. Но LCG, похоже, применим только к динамическим методам. Меня беспокоит тип со всеми его геттерами/сеттерами свойств, которые теперь больше не требуются. Если это выделено в неуправляемой куче, наша единственная надежда на освобождение памяти, по-видимому, состоит в том, чтобы убедиться, что тип загружен во временный домен приложения, который мы можем выгрузить, когда он больше не требуется.

Может кто-нибудь, пожалуйста, подтвердите или выделите другой способ восстановления памяти.

Спасибо


person Carel    schedule 30.09.2010    source источник


Ответы (2)


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

На заре CLR есть две ссылки, которые могут оказаться полезными: Выгрузка сборки и Почему нет ли метода Assembly.Unload?.

Вы смотрели DLR? Возможно, что-то вроде ExpandoObject может вам помочь, хотя выглядит подобное в настоящее время не поддерживается для привязки данных в Silverlight 4 (возможно, в Сильверлайт 5?)

person Samuel Jack    schedule 30.09.2010
comment
ExpandoObject, безусловно, является вариантом, но, как вы упомянули, не поддерживается в SL4. Спасибо за подтверждение. - person Carel; 01.10.2010

.NET 4.0 представляет концепцию собираемых сборок, которые имеют право на сбор мусора. Пример использования можно найти здесь.

person desco    schedule 30.09.2010
comment
К сожалению, коллекционные сборки в настоящее время не поддерживаются Silverlight, и именно здесь возникает проблема (я делаю вывод об отсутствии поддержки, потому что необходимый флаг RunAndCollect отсутствует в перечислении AssemblyBuilderAccess в документации Silverlight 4: msdn.microsoft.com/en-us/library/2e88sa1d(v=VS.100) .aspx) - person Samuel Jack; 01.10.2010
comment
печально. В этом случае да - сгенерированные сборки останутся в памяти и будут удалены только тогда, когда содержащий AppDomain будет выгружен. - person desco; 01.10.2010
comment
Не знал о коллекционных сборках. Полезно знать о его существовании. Жаль, что это не поддерживается в SL. - person Carel; 01.10.2010