2012-04-18 9 views
2

解析するテキストファイルが非常に大きい(〜2GB)。いろいろな理由から私はファイルを行ごとに処理する必要があります。私はvar records = Regex.Split(File.ReadAllText(dumpPath, Encoding.Default), @"my regex here").Where(s => !string.IsNullOrEmpty(s));でテキストファイルをメモリにロードすることで(パーサに十分なメモリがあるサーバーをロードしています)これは、テキストファイルのサイズに相当するRAMと、IEnumerableのオーバーヘッドのための数MBを消費します。ここまでは順調ですね。 その後、私はforeach (var recordsd in records) {...}foreachループを使用して大きなテキストファイルを解析する奇妙な動作(C#.NET 4)

とここで興味深い部分が来てコレクションを行きます。私はforeachループで文字列操作と正規表現をたくさん行います。 foreachループで数kB以上を使用することはありませんが、プログラムはSystem.OutOfMemoryExceptionで素早く爆撃します。 私の選択したプロファイラ(ANTSメモリプロファイラ)を使用していくつかのメモリスナップショットを作成し、ヒープ上の何百万も何百万という第2世代の文字列オブジェクトを見て、使用可能なメモリをすべて消費しました。それを見て

は、I - 単なるテストとしては、 - 各foreachの反復の終わりにGC.Collect();を含め、出来上がり、問題は永久的なガベージコレクションプログラムの案の定(解決しないとメモリの例外のうち、それ以上今は辛抱強く遅く走る)。消費される唯一のメモリは、実際のファイルのサイズです。

今、なぜこのようなことが起こり、どのように防止するのか説明できません。私の理解には、変数が有効範​​囲外になり、もはやガベージコレクションのマークが付いた(アクティブな)参照がなくなってしまったのでしょうか?

別のメモでは、私は本当に大規模なマシン(64GBのRAM)でプログラムを実行しようとしました。プログラムは正常に終了しましたが、閉じられる前に1バイトのメモリが解放されませんでした。どうして?オブジェクトへの参照がなくなり、オブジェクトが有効範囲外になった場合、メモリが解放されないのはなぜですか?

+1

ここ2世代で文字列が終わるのは本当ですか? gen0クリーンアップとgen1クリーンアップの両方を見逃してしまっても、どうにかしてそれらを保持しなければなりません。サイドノート。 'GC.Collect(2、GCCollectionMode.Optimized)'を実行すると、コレクションを高速化できます。 – adrianm

答えて

5

今、私はこれがなぜ起こるのか、それを防ぐ方法を説明できません。私の理解には、変数が有効範​​囲外になり、もはやガベージコレクションのマークが付いた(アクティブな)参照がなくなってしまったのでしょうか?

号は、ガベージコレクションのために「マーク」されているようなものはありません、とゴミではありません変数が収集:オブジェクトです。すでにgen2に入っているオブジェクトは、GCが次にgen2を見るまでガベージコレクションされません。これは比較的まれです。

私はさまざまな理由から、ファイルをライン単位で処理する必要があります。

答えがあります:.NET 4を使用している場合はFile.ReadLinesを使用し、そうでない場合は同等(簡単です)を書いてください。次に、一度にメモリ内のファイル全体を必要としません。あなたのメモリ使用量は絶対に激減するはずです。 (つまりReadLinesないReadAllLinesだということに注意してください - 。後者は、あなたが望むものではない文字列の配列、にファイル全体を読み込みます)

を別のサイドノートで、私はプログラムを実行しようとしました非常に大規模なマシン(64GBのRAM)で。プログラムは正常に終了しましたが、閉じられる前に1バイトのメモリが解放されませんでした。どうして?

あなたは、プロセスは、オペレーティング・システムから取ることメモリの話をしている場合は、私がはCLRが今までメモリを解放を信じていません。私は、あなたが一度多くのメモリを使用していたら、おそらくそれをもう一度使用するというアプローチをとると思います。

+0

私はおそらくあまりにも速く入力し、私が実際に書いたものを再読しなかった。だから、私はテキストファイル上でたくさんのランダムアクセスをしているので、私はさまざまな理由でメモリにテキストファイル全体が必要です。また、私はちょうど私が見ているものの説明をしたかった。ありがとう。 – lightxx

+0

ちょっと物事を詳しく説明しています。このファイルは、あまりにも不明瞭なファイル形式のDNAサンプリング装置によって生成される。いくつかのDNAサンプルは複数のラインに広がり、他のものはそうしない。 1行にある値の解釈は、他の行にある値に依存します。等々。その巨大なテキストファイルを分析してDBに保存するカスタムオブジェクトの集合に変換することが目標です。すべてのことを説明するのはちょっと複雑ですが、解析中にファイル全体を見ることが重要です。私が知る必要があるのは、なぜGC.Collect()を呼び出しているかです。問題を解決するように思われ、それについて何をするのですか – lightxx

+0

私はあなたのコメントをupvoteしたいが、私の担当者は低すぎる:( – lightxx

関連する問題