2009-04-07 13 views
3

プロダクションコードリリースの例外ログがあります。大容量ファイルの処理時にRegexのOutOfMemoryExceptionが発生する

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

処理しようとしたデータは約800KBでした。

私のローカルテストでは、正常に動作します。同じような動作を見たことがありますか?その原因は何ですか?

私はそれを処理する前にテキストを分割する必要がありますが、明らかにその場合正規のファイルがランダムな場所から分割されているため、正規表現が一致しないことがあります。

私の正規表現:

EDIT 2:

私はそれがすぐにメモリを食べている隔離された環境でそれをテストする場合、この特定の正規表現は、問題を引き起こしていると思います。

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

EDIT

私は私の地元のテストで間違ってされていました。大きな文字列を読み込んで.NET Frameworkをめちゃくちゃにして、文字列操作中ではなくRegEx中にOOM例外を与えました(またはランダムに、前に述べたものを無視します)。

これは.NET Framework 2.0アプリケーションです。

+0

正規表現を使用しているコードをリストできますか? – Seibar

答えて

2

あなたのRegexを見ることなく、わかりませんが、あなたの試合がレイジーの代わりにグリーディであるため、このような問題が発生することがあります。

Regexエンジンは多くの情報を内部的に保存しなければならず、GreedyのマッチによってRegexは800k文字列の大きな部分を何度も選択することになります。

here以上の情報があります。

+0

質問に私の正規表現を入れてください。 –

+0

あなたは一致させようとしていることの小さなスニペットを持っていますか?それはHtmlですか、それともURLが入っている可能性のあるテキストですか? –

+0

最新の正規表現では、最後の '*'を '*'に変更するとどうなりますか? –

1

私が試してみたいことは、アプリケーションで可能であれば、入力を分割することです。

ファイル(入力がファイルの場合)を行単位で読み込み、正規表現をそのように適用できますか?

CLR Profilerをご覧ください。使用方法を学ぶには少し時間がかかるかもしれませんが、それはそれだけの価値があります。オブジェクトが使用するメモリ量を視覚化するのに役立ちます。

+0

2つの問題があります。私は元々、正規表現のオプションとしてSingleLineを使用しています。だから行ごとにそれを読むことはいくつかの正規表現を壊すかもしれません。第2に、これは短いファイルに悪いパフォーマンスの影響があります(明らかに私はサイズに依存して切り替えても問題ありません:)しかし、私はそれを修正できない場合は良いアイディアです) –

+0

私は、小規模なファイルのためのラインと正規表現を一度に適用することは、それが顕著な影響を及ぼさないほど十分に小さくなるだろう。 – Seibar

+0

ええ、私はそれをテストし、それが動作するかどうかを確認する必要があります。 –

1

あなたの編集に基づいて、あなたのコードが大量のメモリを占める文字列を作成しているように思えます。これは、たとえメモリ不足例外がRegexコード内から生成されたとしても、Regex自体があまりにも多くのメモリを占有しているためではありません。したがって、独自のコードでStringBuilderを使用して問題を解決した場合は、それを行う必要があります。

+0

ちょうどあなたが正しいです、私はちょうどそれを考え出し、私のサンプルを更新しました。これは元のコードの動作ではありませんでしたが、これはテストコードでした。私の最終編集をチェックしてください。 –

関連する問題