Утечка памяти C# RuntimeBinder (динамическое ключевое слово?)
В настоящее время я работаю над огромным C# проектом, взаимодействующим с Excel. Мы обнаружили, что с некоторыми файлами Excel ресурсы памяти растут в геометрической прогрессии. Через 2 или 3 часа Excel вылетает.
Я установил ANT Memory Profiler, который, казалось, был довольно хорош для анализа утечек памяти в проектах C#, и я был довольно смущен, увидев, что все утечки происходят из классов, о которых я никогда не слышал.
Эта ссылка довольно хорошо суммирует результаты, которые я получил: Переполнение памяти: увеличение числа Microsoft.CSharp.RuntimeBinder.Semantics
Ссылка говорит, что проблема может быть связана с использованием динамического ключевого слова. НО проблема в том, что мы не используем это ключевое слово в нашем коде.
Однако мы используем: Microsoft.Office.Interop.Excel
которая является DLL, нам нужно взаимодействовать с Excel. Изучив их код, мы увидели, что это динамическое ключевое слово используется в некоторых их классах для определения их свойств. Мы последние используем те же свойства в нашем коде в нескольких местах. Но это означает, что у нас нет власти над этими свойствами и что мы не можем использовать решения, предложенные в последней ссылке или даже в этой: утечка в RuntimeBinder при использовании ключевого слова "dynamic" с __ComObject
Например, это определено так в dll:
dynamic ActiveSheet { get; }
и мы используем его следующим образом (рабочий лист является объектом Excel.Worksheet):
worksheet = theWorkbook.ActiveSheet;
Кроме того, я даже не знаю, происходит ли проблема из-за этих динамических ключевых слов, поэтому, возможно, я полностью отвлекаюсь от реального решения.
редактировать
Я не могу знать, в каком методе происходит сбой, мы используем потоки для вызова API, информация, которую мы восстанавливаем, помещается в ячейки Excel. API вызывается несколько раз в секунду. Так что я думаю, что некоторые данные хранятся в памяти, когда ячейка обновляется, а не удаляется.
Вот экран того, что дает мне профилировщик ANT:
Так как мы никогда не используем эти классы CSharp, я не знаю, что является источником этих утечек, ни в каком методе это происходит, и, поскольку он является многопоточным и автоматизированным, нет никаких действий пользователя, которые могли бы сообщить нам, когда именно происходит утечка.
Мы используем Marshal.ReleaseComObject
везде, где мы можем, но я думаю, что легко пропустить один... Требуется проверка