- PR -

OutOfMemoryExceptionの対策について

投稿者投稿内容
きくちゃん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 854
お住まい・勤務地: 都内某所
投稿日時: 2006-05-17 09:50
Draさん、お早うございます。

引用:

レコード毎にbyte数が異なる為Readメソッドの使用は難しいと考えられます。


いや、読みとるデータは、レコード毎である必要はありません。
CR/LFを頼りに、自力で「レコード」を組み立てれば良いんです。

引用:

エラーに関しては、「種類 System.OutOfMemoryException の例外がスローされました。」
のみしかとれません。


デバッグ実行して、キャッチした例外の StackTrace を確認すれば、もう少し詳細な情報が得られますよ。
Dra
大ベテラン
会議室デビュー日: 2004/10/04
投稿数: 111
投稿日時: 2006-05-17 10:07
きくちゃんさん、ありがとうございます。
>CR/LFを頼りに、自力で「レコード」を組み立てれば良いんです。
対応は保留中です。

>StackTrace を確認すれば
なぜかわかりませんがStackTrace情報はnothingです。
うにくま
ベテラン
会議室デビュー日: 2005/11/05
投稿数: 82
投稿日時: 2006-05-17 10:27
引用:

なぜかわかりませんがStackTrace情報はnothingです。


ごめんなさい。
私の方でも試してみましたが、OutOfMemoryExceptionの場合は種類以外は取得できないみたいです。
言われてみれば確かにそうですよね。
きくちゃん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 854
お住まい・勤務地: 都内某所
投稿日時: 2006-05-17 10:51
引用:

うにくまさんの書き込み (2006-05-17 10:27) より:
私の方でも試してみましたが、OutOfMemoryExceptionの場合は種類以外は取得できないみたいです。


おっと、いい加減な事を書いてしまったみたいですね。
失礼しました。

甕星さんの情報も気になるんですが、Xpとかで試してみた結果も教えて下さいね。>Dra さん。
Dra
大ベテラン
会議室デビュー日: 2004/10/04
投稿数: 111
投稿日時: 2006-05-17 11:07
OSに関しては、Win2000、WinXPで試しました。また.NET2002,2003及びC#に変換し試しましたがまったく同じ結果となりました。
データの問題かどうかも確認できません。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-05-17 11:19
引用:

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

データの問題かどうかも確認できません。


これは、"正しく読めることが確定している行" を 300MB になるまで、
延々とコピーしたファイルで試せば確認できますよね。

また、提示された部分だけのソースで動作させていますか?
新規プロジェクトを生成し、単純に Button を 1 つだけ配置し実行してみてください。
(ミニマム コードで試した方が良いということです)

このように、問題の「切り分け」をどんどんしていく必要があります。
もし試されているのであれば、洗いざらい書いてくださった方が良いです。

引用:

OSに関しては、Win2000、WinXPで試しました。


マシンを変えても再現したことから、少なくとも環境依存ではなさそうですね。
(こうやって「切り分け」して狭めていきます)

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-05-17 23:28
 ふと気になった。

> System.IO.StreamReader("読込みファイル", System.Text.Encoding.Default)
> System.IO.StreamWriter("書込みファイル", False, System.Text.Encoding.GetEncoding(932))

 読み込むファイルは、Default コード ページ(Windows 2000 だから UTF-8?)で、人間が文字として認識できる文字のみが書き込まれているのだろうか?
引用:

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

書き込んでいるファイルのサイズが202322KB(198MB)で毎回エラー発生となります。
何か原因があるのでしょうか?


Draさんの書き込み(2006-05-16 00:59)より:

ファイルの読み込みでエラーが発生しています。20万行目くらいです。


 ReadLine で例外が発生するということは、ここまで(20万行目くらいまで)は正常と判断できると思います。
 StreamReader を直接開くのではなく、seek 可能なストリームから StreamReader を作り、例外が発生する直前の位置を取得する。例外が発生したらプログラムを修正して、さっきまで進んでいた位置に飛ばす。そして実行すると、データが累積するのが悪いのか、ファイルのが悪いのか、判断できるでしょう。
コード:
Dim stream As Stream = Nothing
Dim reader As StreamReader = Nothing
Dim pos As Long = 0L ' これを換える
Try
    stream = New FileStream(file_name, FileMode.Open, FileAccess.ReadWrite)
    stream.Position = pos
    Try
        reader = New StreamReader(stream, エンコード)
        Dim line As String = reader.ReadLine()
        Dim lnum As Long = 1L
        While Not reader Is Nothing
            System.Diagnostics.Debug.WriteLine(String.Format("{0:d} : {1:d}", stream.Position, lnum)
            line = reader.ReadLine()
            lnum += 1L
        End While
    Finally
        If Not reader Is Nothing Then
            reader.Close()
        End If
    End Try
Finally
    If Not stream Is Nothing Then
        stream.Close()
    End If
End If



 UNIX マシン、または Cygwin などの UNIX コマンドが使える環境があるなら、wc -l で行数を数え、tail で20万行目以降を別のファイルに落とすことも出来るでしょう。

 コマンドプロンプトから、type コマンドで出力することも出来そう。more コマンドは、落ちるかな?

 あるいは、そのファイルが正しく(仕様通りか、こちらの意図通り)出力されていることは、どうやって確認したのでしょう?
ベテラン
会議室デビュー日: 2005/05/16
投稿数: 85
お住まい・勤務地: 千葉県在住
投稿日時: 2006-05-19 09:32
Draさんこんにちは。

Stringは値を代入する度に、内部的に新たなStringクラスが作成されると
記憶しています。
以前、.NET開発していた際にも、コード分析を行った方から、Stringに対し
「+=」のような記述を多用する場合は「StringBuilder」を使うべきだと
指摘された事があります。

ぶさいくろうさんも仰っていましたが、「strLine」をWhileの内側で宣言する
方法が良いかもしれません。
或いは、「strLine」をStringBuilderで宣言し、「ReadLine」の直前に
「strLine」を「Remove」する事で、メモリの消費を抑えられそうな気がします。

これでも解決されないようであれば、余分な(処理に影響の無い)コードを
削ぎ落とすなどして、問題点の切り分けを地道にして行くしかなさそうですね。

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