2

私のアプリケーションでは、Windows サービスを使用してファイルを読み込んでいます。このサービスは、毎秒ファイルを読み取ります。これは、ファイルを読み取るために使用しているコードです。

public static byte[] GetBytesFromFile(string fullFilePath)
{
    FileStream fs = File.OpenRead(fullFilePath);
    try
    {
        byte[] bytes = new byte[fs.Length];
        fs.Read(bytes, 0, Convert.ToInt32(fs.Length));
        fs.Close();
        return bytes;
    }
    finally
    {
        fs.Close();
    }
}

数時間後、私はSystem.OutOfMemoryException. 私はここで何か悪いことをしていますか?

更新: このコードで返されたバイトを使用しています:

object s = null;
System.Reflection.Assembly a = Assembly.Load(bytes);
object o = a.CreateInstance("ID_" + report.ID.ToString().Replace("-", "_"));

Type t = o.GetType();
MethodInfo mi = t.GetMethod(name);
object[] values = new object[1];
values[0] = nameValue;
s = mi.Invoke(o, values);
return s;
4

1 に答える 1

4

編集すると、問題は明らかです。

System.Reflection.Assembly a = Assembly.Load(bytes);

ここに問題があります: アセンブリはからアンロードされませんAppDomain。-のようなガベージ コレクション可能なものがありますがDynamicMethod、完全なアセンブリではありません。アセンブリをロードしている場合、それを行う唯一の安全な方法はAppDomain、プロセス内で別のものにすることです。次に、作業が完了したら、を投棄できますAppDomain(これにより、その中にあるすべてがアンロードされます)。


実際には、既存のコードが機能Readするという保証はありません。すべてのデータを読み取ることを保証するものではありません。私はそれについて保留中のブログ投稿を持っています...

ただし、ファイルが大きい場合は、非圧縮ヒープである LOH をゆっくりと飽和させている可能性があります。私が提供できる最善のアドバイスは、巨大なファイルを配列に読み込まないことです。StreamAPI、ある種の「リーダー」API、またはある種の解析反復子ブロックのいずれかで動作するように、ダウンストリーム コードを書き直してみてください。

コードの残りの部分がどのように処理されるかを確認しないと、それ以上のことは言えません。ただし、コードでメモリ プロファイラを実行してbyte[]、メモリの問題の原因が実際に であることを確認することをお勧めします。

于 2013-02-25T08:15:35.823 に答える