.NET расследование “Утечки памяти” RegEx

Я недавно изучил некоторую.NET "утечки памяти" (т.е. неожиданный, непрекращающийся GC базировался объекты) в приложении WinForms. После загрузки и затем закрытия огромного отчета, использование памяти не отбрасывало как ожидалось даже после нескольких gen2 наборов. Предположение, что управление созданием отчетов поддерживалось случайным обработчиком событий, я взломал WinDbg для наблюдения то, что происходило...

Использование WinDbg, !dumpheap -stat команда сообщила, что большой объем памяти был использован строковыми экземплярами. Далее совершенствовав это вниз с !dumpheap -type System.String управляйте, чтобы я нашел преступника, строка 90 МБ используемый для отчета, в адресе 03be7930. Последний шаг должен был вызвать !gcroot 03be7930 видеть, какой объект (объекты) поддерживал его.

Мои ожидания были неправильными - это не был отсоединенный обработчик событий, зависающий на управление созданием отчетов (и строка отчета), но вместо этого это состоялось a System.Text.RegularExpressions.RegexInterpreter экземпляр, который сам является потомком a System.Text.RegularExpressions.CachedCodeEntry. Теперь, кэширование Regexs является (несколько) общепринятой истиной, поскольку это помогает уменьшить издержки необходимости перекомпилировать Regex каждый раз, когда это используется. Но что затем это имеет отношение к поддержанию моей строки?

На основе анализа с помощью Отражателя оказывается, что входная строка хранится в RegexInterpreter каждый раз, когда метод Regex называют. RegexInterpreter содержит на эту строковую ссылку, пока новая строка не питается в него последующим вызовом метода Regex. Я ожидал бы подобное поведение путем зависания на Regex. Экземпляры соответствия и возможно другие. Цепочка - что-то вроде этого:

  • Regex. Разделение, Regex. Соответствие, Regex. Замена, и т.д.
    • Regex. Выполненный
      • RegexScanner. Сканирование (RegexScanner является базовым классом, RegexInterpreter, является подклассом, описанным выше).

Оскорбление Regex только используется для создания отчетов, редко используемое, и поэтому вряд ли использоваться снова для убирания существующей строки отчета. И даже если бы Regex использовался позже, то он, вероятно, обработал бы другой большой отчет. Это - относительно значительная проблема и просто чувствует себя грязным.

Однако я нашел несколько опций о том, как решить, или по крайней мере работать вокруг, этот сценарий. Я позволю сообществу ответить сначала и если никакие берущие не выступят вперед, то я заполню любые разрывы через день или два.

14
задан Kevin Pullin 29 April 2010 в 04:26
поделиться

2 ответа

Используете ли вы экземпляры Regex или статические методы Regex, которые принимают шаблон строки? Согласно этому сообщению , экземпляры Regex не участвуют в кешировании.

8
ответ дан 1 December 2019 в 16:15
поделиться

Попробуйте переключиться на скомпилированное регулярное выражение - создание экземпляра займет больше времени, но, возможно, не будет подвержено этой странной утечке.

См. http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regexoptions%28v=VS.100%29.aspx для получения дополнительной информации.

Или не держите экземпляр Regex дольше, чем нужно - создавайте новый для каждого вызова отчета.

0
ответ дан 1 December 2019 в 16:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: