2012-01-29 6 views
6

.NET 4.0で作成されたWindowsサービスがあります。このサービスは、カンマ区切りの値の行で構成される大きなテキストファイルを解析します(数百万行、 10の値)、ここでは問題はありません。ラインを読み取ってキー/値コレクションに分割し、値を処理できます。 データパラレル化を使用している値を検証するには、値(基本的に特定の形式の値の配列)を個々の値に対してRegEx検証を実行するメソッドに渡します。RegExと異なるフレームワークバージョンのメモリ使用量と既知の問題

静的RegEx.IsMatchメソッドではなく、RegexOptions.Compiledとして定義された静的RegExプロパティを静的正規表現で使用しました。我々は、かなり標準的なメモリ・フットプリントを持っていたこの方法を使用

private static Regex clientIdentityRegEx = new Regex("^[0-9]{4,9}$", RegexOptions.Compiled); 

メモリは、各行の値の大きい数でわずかに増加し、かかる時間は、多かれ少なかれ総ライン数に直線的でした。

さまざまなフレームワークバージョンの他のプロジェクトで正規表現を使用できるようにするため、静的なRegExプロパティを最近.NET 2.0のCLRを使用してコンパイルされた一般的なユーティリティプロジェクトに移動しました(実際の正規表現は変更された)RegExプロパティの数は、25程度から約60に増加しました。これを実行して以来、私たちはメモリ問題に遭遇し始めました。オリジナルのプロジェクトの3倍以上のメモリが増加しました。実行中のサービスをプロファイリングすると、RegEx.IsMatchからメモリが漏れているように見えます。RegEx.IsMatchでは、特定のRegExではなく、どのメモリが呼び出されているかによってさまざまです。

.NET 1.0/1.1 RegExに関するBCLチームの古いMSDN blog postに次のコメントが見つかりました。

コンパイルにはさらにコストがかかりますが、 Reflection.Emitを使ってILを書き出すとコードが大量に読み込まれ、大量のメモリが使用されます。これはあなたが戻ってくるメモリではありません。加えて。 v1.0とv1.1では、私たちが生成したILを解放することはできませんでした。つまり、このモードを使用してメモリをリークしました。私たちはWhidbeyでこの問題を解決しました。しかし、結論は、あなたが繰り返し使用されることがわかっている有限の式のセットに対してのみ、このモードを使うべきだということです。

一般的なRegEx呼び出しの「ほとんどの」プロファイルを作成し、個別に問題を複製することはできません。

これは.NET 2.0 CLRの既知の問題ですか?記事で

は作家ですを述べ、「しかし、一番下の行は、あなただけが繰り返し使用されます知っている表現の有限集合のために、このモードを使用する必要があるということである」有限である可能性が高いものを、をこの方法で使用される式の数は、これが原因である可能性がありますか?

更新: @Henk Holtermanからの回答に沿って任意のベストプラクティス正規表現をテストするベンチマークの、ボリュームとパラメータ形式で純粋なブルートフォースを使用するよりも、他の特別RegEx.IsMatchは、ありますか?

答え:答え:「限られた固定数のRegExオブジェクトを必要とするシナリオ」のハンクスの回答はかなり目立っていましたが、静的なRegEx'esをクラスに追加して、メモリの使用状況では、これらは静的クラスを分離するように移行され、メモリの問題のいくつかを解決したようです。

私は確信することはできませんが、.NET 2.0 CLRと.Net 4.0 CLRの間でコンパイルされたRegExの使用には違いがあります。メモリの問題は.NET 4.0フレームワーク。 (任意の確認?)

+1

OK、あなたのコードを再構築し、RegExのnrをかなり上げました。あなたは一度に1つ戻ることができますか? –

+0

プロファイラは正確に何を伝えますか?メモリリークの種類について? –

+0

はい、私たちは今日遅く、.NET 2.0のCLRにコンパイルされたプロジェクトで、これまでに使用されていたRegExとまったく同じ数のメモリを増やしましたが、追加した数には直接関係はありませんと表現の型が呼び出されます。 – Lloyd

答えて

1

このシナリオでは、限られた固定数のRegExオブジェクトが必要です。それは漏れてはいけません。新しい状況では、RegExオブジェクトがまだ再利用されていることを確認する必要があります。

他の可能性は、増加した数(60から25)の式です。それらのうちの1つだけが多少複雑になり、過度のバックトラックにつながる可能性がありますか?

関連する問題