У меня есть приложение, изначально написанное на VB6, которое я использовал инструмент для преобразования в C # с довольно неплохим успехом с функциональной точки зрения. Он обрабатывает большой объем сообщений с использованием большого количества объектов COM (C ++) малого и среднего размера.
Я заметил, что конкретный тестовый запуск в старом приложении VB6, который работал с использованием менее 40 МБ памяти, требовал почти 900 МБ в приложении C #. Если я помещаю GC.Collect () в самый внутренний цикл обработки сообщений приложения C #, он использует столько же или меньше памяти, что и приложение VB6, хотя тогда он действительно очень медленный. Это заставляет меня думать, что «утечки» в абсолютном смысле слова нет.
Затем я запустил приложение C # через профилировщик памяти AQTime, и он сообщил, что в куче находится чрезмерное количество объектов COM / C ++. Я предположил, что это произошло из-за того, что вызываемые оболочки времени выполнения вокруг COM-объектов были довольно маленькими и никогда (или редко) запускали сборку в C #, даже если их COM-объекты, на которые они ссылаются, были значительно больше. Я думал, что могу решить эту проблему, добавив явные вызовы Marshal.ReleaseComObject () вокруг COM-объектов в приложении C #. Я пошел и сделал это во многих местах, где время жизни COM-объектов было легко определить. Я заметил лишь очень небольшое уменьшение использования памяти.
Мне интересно, почему я не добился большего успеха в этом. Просматривая статические методы в классе Marshal, я вижу некоторые, которые наводят меня на мысль, что либо мне не хватает тонкости в обработке ссылок COM, либо мое предположение о том, что они немедленно уничтожаются, когда счетчик ссылок RCW достигает нуля, неверно. .
Я был бы признателен за любые предложения по другим подходам, которые я мог бы попробовать, или другие вещи, которые я, возможно, упустил или неправильно понял.