Question

J'ai un journal d'exception de l'une des versions de code de production.

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()

Les données qu'il essaie de traiter était d'environ 800 Ko.

Dans mes tests locaux, il fonctionne parfaitement bien. Avez-vous déjà vu un comportement similaire, ce qui peut être la cause?

Dois-je diviser le texte avant de le traiter, mais il est évident dans ce cas regex peut ne pas correspondre parce que la scission du fichier d'origine à partir d'un lieu au hasard.

Mes Regexes:

EDIT 2:

Je pense que ce particulier RegEx est à l'origine du problème, quand je le tester dans un environnement isolé, il mange la mémoire instantanément.

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

EDIT

J'étais pas avec mon test local. Je chargeais une grande chaîne annexant puis choses à ce qui rend .NET Framework étourdie et puis donner une exception OOM au cours de la RegEx au lieu de pendant les opérations de chaîne (ou au hasard, donc ignorer les choses précédente je l'ai dit).

Ceci est une application .NET Framework 2.0.

Était-ce utile?

La solution

Sans voir votre Regex, je ne sais pas pour sûr, mais parfois vous pouvez obtenir des problèmes comme celui-ci parce que vos matchs sont cupides au lieu de Lazy.

Le moteur Regex doit stocker beaucoup d'informations en interne et les matches Greedy peut finir par causer la Regex pour sélectionner une grande partie de votre chaîne de 800K, à plusieurs reprises.

Il y a quelques bonnes informations à ce sujet sur .

Autres conseils

Selon votre édition, il semble que votre code peut créer des chaînes qui prennent de grandes quantités de mémoire. Cela signifie que même si l'exception de la mémoire est générée à partir dans le code Regex, ce n'est pas en réalité parce que le Regex lui-même prend trop de mémoire. Par conséquent, si vous utilisez StringBuilder dans votre propre code résout le problème, alors que ce que vous devez faire.

La première chose que je voudrais essayer, s'il est possible pour votre application, serait de diviser l'entrée.

Serait-il possible de lire le fichier (si l'entrée est un fichier), ligne par ligne, en appliquant l'expression régulière de cette façon?

Vous devriez jeter un oeil à CLR Profiler . Il peut prendre un peu de temps pour apprendre à utiliser, mais il vaut la peine. Il vous aidera à visualiser la quantité de mémoire utiliser vos objets.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top