Я написал многопоточное неуправляемое приложение, которое использует 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 #, как в основном потоке, так и в другом созданном потоке. В обоих случаях утечка памяти исчезла. Кажется, что необходимо перейти от неуправляемого кода к управляемому и обратно. Удаление любой его части приводит к исчезновению проблемы.