- PR -

OutOfMemoryExceptionの対策について

投稿者投稿内容
Dra
大ベテラン
会議室デビュー日: 2004/10/04
投稿数: 111
投稿日時: 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
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-05-15 13:51
引用:

Draさんの書き込み (2006-05-15 13:29) より:

読み込むファイルのサイズが4GB程度あり(書き込み後の想定は1GB程度)、
処理中にSystem.OutOfMemoryExceptionが発生します。


不思議ですね、解放が追いつかないものなんでしょうか。
Thread.Sleep メソッドを挟むことで、改善するかどうか確認してみてください。

引用:

sw.Write(strLine)
sw.Write(vbCr + vbLf)


WriteLine メソッドを使うべきだと思います。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2006-05-15 14:43
引用:

処理中にSystem.OutOfMemoryExceptionが発生します。



1行分の処理が終わったところで、GC.Collect() するようにしてみてください。

囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2006-05-15 15:07
StreamWriter の方も一行処理が終わるたびに適当に Flush() しないといけないのかも知れませんね。(1GB を抱えたままはでかすぎる。)
_________________
囚人のジレンマな日々
Dra
大ベテラン
会議室デビュー日: 2004/10/04
投稿数: 111
投稿日時: 2006-05-15 17:23
じゃんぬねっとさん、渋木宏明(ひどり)さん、囚人さんありがとうございます。
遅れてすいません。

まず、WriteLineを使用しある行単位でSleepを使用しましたが、メモリー
はうまいこと開放されていないようでした。
GC.Collect()を試してみます。

Dra
大ベテラン
会議室デビュー日: 2004/10/04
投稿数: 111
投稿日時: 2006-05-15 17:42
GC.Collect()を試しました。
Sleep処理を使用するよりは、行の読込み・書込みは多くなりましたが
同様にSystem.OutOfMemoryExceptionが発生します。

Flush()の使用については、理解していない為調べて試してみます。

他に何かよい処理があればご教授願います。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-05-15 18:16
引用:

Draさんの書き込み (2006-05-15 17:42) より:

Flush()の使用については、理解していない為調べて試してみます。


ということは AutoFlush のままと考えた方が良さそうですね。
囚人さんが懸念されていることが当たっているとすれば、
AutoFlush が追いついていないことに... いや、そんなことはないような...

とりあえず、AutoFlush プロパティ を false に設定しておいて、
繰り返しの最後に Flush メソッド を含めてみてください。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2006-05-15 19:02
OSはWindows2000ですか?最新のSPはあててますか?タスクマネージャで見ると、システムキャッシュが大きくなっていませんか?.NET以前の話ですが、大きなファイルにシーケンシャルにI/Oすると、メモリ不足に陥る不具合があったような気が・・・。

#その時には適当にSleepを入れて、リトライすることで逃げました。

スキルアップ/キャリアアップ(JOB@IT)