Прелюдия
Рассмотрим следующий код:
var comType = Type.GetTypeFromCLSID(new Guid("E13B6688-3F39-11D0-96F6-00A0C9191601"));
while (true)
{
dynamic com = Activator.CreateInstance(comType);
Marshal.FinalReleaseComObject(com);
}
Сигнатура метода Marshal.FinalReleaseComObject выглядит следующим образом:
public static int FinalReleaseComObject(Object o)
Создаем простой COM-объект, выполняем какую-то работу и тут же его освобождаем. Казалось бы, что может пойти не так? Да, создание объекта внутри бесконечного цикла — не очень хорошая практика, но GC возьмет на себя всю грязную работу. Реальность оказывается несколько иной:

Чтобы понять, почему утекает память, нужно разобраться в том, как работает dynamic. На Хабре уже есть несколько статей на эту тему, например эта, но они не углубляются в детали реализации, так что проведем собственное исследование.
Читать полностью »