OutofMemoryException في مباريات Regex عند معالجة الملفات الكبيرة

StackOverflow https://stackoverflow.com/questions/725817

سؤال

لدي سجل استثناء من أحد إطلاقات رمز الإنتاج.

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

البيانات التي تحاول معالجة حوالي 800 كيلو بايت.

في اختباراتي المحلية، يعمل بشكل جيد تماما. هل سبق لك أن رأيت سلوكا مماثلا، ما يمكن أن يكون السبب؟

يجب أن أقسيم النص قبل معالجةه، ولكن من الواضح أنه في هذه الحالة قد لا يتطابق Regex لأن الملف الأصلي تقسيم من مكان عشوائي.

بلدي regexes:

تحرير 2:

أعتقد أن هذا Regex الخاص يسبب المشكلة، عندما يمكنني اختباره في بيئة معزولة، فإنه يأكل الذاكرة على الفور.

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

تعديل

كنت مخطئا في اختباري المحلي. كنت جرس سلسلة كبيرة ثم إلحاق الأشياء التي تجعله مما يجعل .NET Framework Dizzy ثم امنح استثناء OOM أثناء Regex بدلا من أثناء عمليات السلسلة (أو عشوائيا، بحيث تجاهل الأشياء السابقة التي قلتها).

هذا هو تطبيق .NET Framework 2.0.

هل كانت مفيدة؟

المحلول

دون رؤية Regex الخاص بك، لا أعرف بالتأكيد ولكن في بعض الأحيان يمكنك الحصول على مشاكل مثل هذا لأن مبارياتك جشع بدلا من كسول.

يتعين على المحرك Regex تخزين الكثير من المعلومات يمكن أن ينتهي المطابقات داخليا والجشع في نهاية المطاف مسببة Regex لتحديد أقسام كبيرة من سلسلة 800K، عدة مرات.

هناك بعض المعلومات الجيدة حول هذا انتهى هنا.

نصائح أخرى

بناء على تحريرك، فإنه يبدو وكأنه رمزك يخلق سلاسل تستغرق كميات كبيرة من الذاكرة. هذا يعني أنه على الرغم من أن استثناء الذاكرة يتم إنشاؤه من داخل رمز Regex، فهذا ليس في الواقع لأن Regex نفسه يتناول الكثير من الذاكرة. لذلك، إذا كان استخدام StringBuilder في التعليمات البرمجية الخاصة بك يحل المشكلة، فهذا ما يجب عليك فعله.

أول شيء سأحاوله، إذا كان ذلك ممكنا للتطبيق الخاص بك، سيتم تقسيم المدخلات.

هل سيكون من الممكن قراءة الملف (إذا كان الإدخال هو ملف) سطر حسب الخط، أو تطبيق التعبير العادي بهذه الطريقة؟

يجب أن نلقي نظرة مع clr profiler.. وبعد يمكن أن يستغرق الأمر القليل من الوقت لمعرفة كيفية استخدامه، لكن الأمر يستحق كل هذا العناء. سوف يساعدك في تصور مقدار الذاكرة التي تستخدمها لكائناتك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top