Я написал многопоточное неуправляемое приложение, которое использует COM-объекты в своих рабочих потоках. Все шло нормально, пока я не начал использовать для работы объекты .NET, экспортированные как COM.
Играя с кодом и комментируя части функциональных возможностей объекта .NET, мне удалось связать это с использованием объектов COM внутри объектов .NET. Обобщить:
- Моя программа запускает пару рабочих потоков.
- Каждый рабочий поток инициализирует COM-объект на основе .NET для выполнения своей работы.
- COM-объекты на основе .NET внутренне используют неуправляемые COM-объекты.
К моему удивлению, потребление памяти приложением начало неуклонно расти, пока не начало появляться исключение OutOfMemory.
Вот моя реализация .NET:
void DoSomeWork()
{
IComObject O = new ComObjectClass();
try
{
// do something
}
finally
{
Marshal.ReleaseComObject(O);
}
}
Если закомментировать эту функцию, утечки памяти исчезнут. Если я вызываю в нем GC.Collect (), утечка памяти все равно происходит.
Есть идеи относительно того, что может происходить?
РЕДАКТИРОВАТЬ: Дополнительная информация на основе комментариев и ответов:
- Все созданные потоки выполняются в MTA.
- Все COM-объекты реализуют IMarshal и используют Free Threaded Marshaler.
- Неважно, что это за что-то - даже int i = 0; i ++; генерирует утечку.
- Объект, отмеченный ComObjetClass, старый и проверен. Это не значит, что он не неисправен, но это не что-то явное.
- Я неоднократно пытался создать COM-объект из программы на C # как в основном потоке, так и в другом созданном потоке. В обоих случаях исчезла утечка памяти. Кажется, что переход от неуправляемого кода к управляемому и обратно очень важен. Удаление любой его части приводит к исчезновению проблемы.