Использование памяти и известные проблемы с RegEx и различными версиями Framework - PullRequest
6 голосов
/ 29 января 2012

У нас есть служба 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 рамки.(Какие-либо подтверждения?)

1 Ответ

1 голос
/ 29 января 2012

Сценарий требует ограниченного фиксированного количества объектов RegEx. Это не должно течь. Вы должны убедиться, что в новой ситуации объекты RegEx все еще используются повторно.

Другая возможность - увеличенное количество (60 из 25) выражений. Может ли только один из них быть немного более сложным, что приведет к чрезмерному откату назад?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...