- - PR -
OutOfMemoryExceptionの対策について
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-05-15 13:29
あるテキスト(CSVファイル)を1行ずつ読込み、条件にあう行のみ別ファイルに書き込み処理
を作成したのですが読み込むファイルのサイズが4GB程度あり(書き込み後の想定は1GB程度)、 処理中にSystem.OutOfMemoryExceptionが発生します。 読み込みの方法等、何か良い対策はないでしょうか? 開発:VB.NET Try Dim srFile As New System.IO.StreamReader("読込みファイル.csv", System.Text.Encoding.Default) Dim sw As New System.IO.StreamWriter("書込みファイル.csv", False, System.Text.Encoding.GetEncoding(932)) '1行ずつ最後まで読み込む Dim strLine As String = "#" While Not strLine Is Nothing '1行ずつ読み込む strLine = srFile.ReadLine() If strLine = Nothing Then '何も読み込まない時はWhile分を抜ける 'Exit While Else Dim str1() As String = strLine.Split(",") If 条件(str1 = "1") Then '書込み処理 sw.Write(strLine) sw.Write(vbCr + vbLf) End If End If End While srFile.Close() sw.Close() Return true Catch ex As Exception Return false End Try | ||||||||
|
投稿日時: 2006-05-15 13:51
不思議ですね、解放が追いつかないものなんでしょうか。 Thread.Sleep メソッドを挟むことで、改善するかどうか確認してみてください。
WriteLine メソッドを使うべきだと思います。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||||||
|
投稿日時: 2006-05-15 14:43
1行分の処理が終わったところで、GC.Collect() するようにしてみてください。 | ||||||||
|
投稿日時: 2006-05-15 15:07
StreamWriter の方も一行処理が終わるたびに適当に Flush() しないといけないのかも知れませんね。(1GB を抱えたままはでかすぎる。)
_________________ 囚人のジレンマな日々 | ||||||||
|
投稿日時: 2006-05-15 17:23
じゃんぬねっとさん、渋木宏明(ひどり)さん、囚人さんありがとうございます。
遅れてすいません。 まず、WriteLineを使用しある行単位でSleepを使用しましたが、メモリー はうまいこと開放されていないようでした。 GC.Collect()を試してみます。 | ||||||||
|
投稿日時: 2006-05-15 17:42
GC.Collect()を試しました。
Sleep処理を使用するよりは、行の読込み・書込みは多くなりましたが 同様にSystem.OutOfMemoryExceptionが発生します。 Flush()の使用については、理解していない為調べて試してみます。 他に何かよい処理があればご教授願います。 | ||||||||
|
投稿日時: 2006-05-15 18:16
ということは AutoFlush のままと考えた方が良さそうですね。 囚人さんが懸念されていることが当たっているとすれば、 AutoFlush が追いついていないことに... いや、そんなことはないような... とりあえず、AutoFlush プロパティ を false に設定しておいて、 繰り返しの最後に Flush メソッド を含めてみてください。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||||||
|
投稿日時: 2006-05-15 19:02
OSはWindows2000ですか?最新のSPはあててますか?タスクマネージャで見ると、システムキャッシュが大きくなっていませんか?.NET以前の話ですが、大きなファイルにシーケンシャルにI/Oすると、メモリ不足に陥る不具合があったような気が・・・。
#その時には適当にSleepを入れて、リトライすることで逃げました。 |