У нас есть служба Windows, созданная в .Net 4.0, службы анализируют большие текстовые файлы, которые состоят из строк значений, разделенных запятыми (несколько миллионов строк, с 5-10 значениями), здесь нет проблем, мы можем прочитатьлинии, разделите их на коллекцию Key / Value и обработайте значения.Для проверки значений мы используем Параллелизм данных для передачи значений, которые в основном представляют собой массив значений в определенных форматах, в метод, который выполняет проверку RegEx для отдельных значений.
До сих пор мы использовали статические регулярные выражения, а не статический метод RegEx.IsMatch, а статическое свойство RegEx со значением RegexOption, определенным как RegexOptions.Compiled, как подробно описано ниже.
private static Regex clientIdentityRegEx = new Regex("^[0-9]{4,9}$", RegexOptions.Compiled);
Используя этот метод, мы имели довольно стандартный объем памяти, память увеличивалась незначительно с большим количеством значений в каждой строке, время, затрачиваемое на то, чтобы быть более или менее линейным по отношению к общему количеству строк.
Чтобы разрешить использование регулярных выражений в других проектах разных версий Framework, мы недавно переместили статические свойства RegEx в общий проект утилит, который теперь компилируется с помощью .Net 2.0 CLR (фактические регулярные выражения).не изменились), количество выставленных свойств RegEx увеличилось примерно до 60 с 25 или около того.После этого у нас начались проблемы с памятью, увеличение памяти в 3 и более раз по сравнению с исходным проектом.Когда мы профилируем работающий сервис, мы видим, что память «протекает» из RegEx.IsMatch, а не из какого-либо конкретного RegEx, но различается в зависимости от того, что вызывается.
Я нашел следующий комментарий к старому Сообщение в блоге MSDN от одного из сотрудников BCL, относящееся к .Net 1.0 / 1.1 RegEx.
Однако стоит упомянуть о еще больших затратах на компиляцию.Emitting IL с Reflection.Emit загружает много кода и использует много памяти, и это не та память, которую вы когда-либо получите.К тому же.в v1.0 и v1.1 мы не могли освободить сгенерированный IL, что означало утечку памяти при использовании этого режима.Мы исправили эту проблему в Whidbey.Но суть в том, что вы должны использовать этот режим только для конечного набора выражений, которые, как вы знаете, будут использоваться неоднократно.
Я добавлю, что мы профилировали «большинство» распространенных вызовов RegEx и не можем воспроизвести проблему по отдельности.
Это известная проблема с .Net 2.0 CLR?
В статье писатели заявляют «Но суть в том, что вы должны использовать этот режим только для конечного набора выражений, который, как вы знаете, будет использоваться многократно» * Что может быть конечным числом выражений, используемых таким образом, и может ли это быть причиной?
Обновление: В соответствии с ответом @Henk Holterman есть ли лучшие практики для тестирования производительности Регулярные выражения, в частности, RegEx.IsMatch, кроме использования чисто грубой силыпо объему и формату параметров?
Ответ: Ответ Хэнкса «Сценарий требует ограниченного, фиксированного числа объектов RegEx» был в значительной степени заметен, мы добавили статические RegEx'ыв класс, пока мы не изолировали выражения с заметным увеличением использования памяти, они были перенесены в отдельные статические классы, что, похоже, решило некоторые проблемы с памятью.
Похоже, хотя я не могу подтвердить это, есть разница между использованием скомпилированного RegEx между .Net 2.0 CLR и .Net 4.0 CLR, поскольку проблемы с памятью не возникают, когда соблюдаются только для .Net4.0 рамки.(Какие-либо подтверждения?)