Pergunta

Eu tenho um log exceção de um dos lançamentos de código de produção.

System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
   at System.Text.RegularExpressions.Match..ctor(Regex regex, Int32 capcount, String text, Int32 begpos, Int32 len, Int32 startpos)
   at System.Text.RegularExpressions.RegexRunner.InitMatch()
   at System.Text.RegularExpressions.RegexRunner.Scan(Regex regex, String text, Int32 textbeg, Int32 textend, Int32 textstart, Int32 prevlen, Boolean quick)
   at System.Text.RegularExpressions.Regex.Run(Boolean quick, Int32 prevlen, String input, Int32 beginning, Int32 length, Int32 startat)
   at System.Text.RegularExpressions.MatchCollection.GetMatch(Int32 i)
   at System.Text.RegularExpressions.MatchEnumerator.MoveNext()

Os dados tenta processar estava prestes 800KB.

Em meus testes locais ele funciona perfeitamente bem. Você já viu um comportamento semelhante, o que pode ser a causa?

Devo dividir o texto antes de processá-lo, mas, obviamente, nesse caso regex pode não corresponder, porque a divisão do arquivo original a partir de um lugar aleatório.

Minha Regexes:

EDIT 2:

Eu penso que este RegEx particular está causando o problema, quando eu testá-lo em um ambiente isolado que está comendo a memória instantaneamente.

((?:( |\.\.|\.|""|'|=)[\/|\?](?:[\w#!:\.\?\+=&@!$'~*,;\/\(\)\[\]\-]|%[0-9a-f]{2})*)( |\.|\.\.|""|'| ))?

Editar

Eu estava sendo errado com o meu teste local. Eu estava carregando uma grande corda, em seguida, acrescentar coisas a ele que faz tonturas .NET Framework e em seguida, dar uma exceção OOM durante o RegEx em vez de durante as operações de cordas (ou aleatoriamente, então ignorar o material anterior eu disse).

Esta é uma aplicação .NET Framework 2.0.

Foi útil?

Solução

Sem ver o seu Regex, eu não sei ao certo, mas às vezes você pode ter problemas como este, porque os seus jogos são gananciosos, em vez de preguiçoso.

O motor de Regex tem de armazenar muita informação interna e partidas Greedy pode acabar causando a Regex para selecionar grandes seções de sua seqüência de 800k, muitas vezes.

Há algumas boas informações sobre este sobre aqui .

Outras dicas

Com base na sua edição, parece que o código pode ser criar strings que ocupam grandes quantidades de memória. Isto significa que mesmo que o fora de exceção de memória é gerado a partir do código de Regex, não é verdade porque o próprio Regex está ocupando muita memória. Portanto, se usar StringBuilder em seu próprio código resolve o problema, então é isso que você deve fazer.

A primeira coisa que eu tentaria, se é possível para sua aplicação, seria dividir a entrada.

Seria possível ler o arquivo (se a entrada é um arquivo), linha por linha, aplicando-se a expressão regular que forma?

Você deve dar uma olhada com CLR Profiler . Pode demorar um pouco de tempo para aprender a usar, mas vale a pena. Ela irá ajudá-lo a visualizar a quantidade de memória seus objetos de uso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top