0

データベースからフェッチするときに、アプリケーションでOutOfMemory例外が発生します。これは、Linq2Sqlを使用するC#.Netアプリケーションです。

GC.GetTotalMemory()データベースの呼び出しの前後にどのくらいのメモリが使用されているかを確認するためにを使用してみました。これにより、何が起こっているのかを正確に把握することはできませんが、わかりやすくなります。Windowsタスクマネージャーを見ると、次のコードを使用してページ形式でデータをフェッチすると、ピークワーキングセットが小さくならないことがわかります。

public static void PreloadPaged()
{
    int NoPoints = PointRepository.Count();
    int pagesize = 50000;
    int fetchedRows = 0;

    while (fetchedRows < NoPoints)
    {
        PreloadPointEntity.Points.AddRange(PointRepository.ReadPaged(pagesize, fetchedRows));
        PointRepository.ReadPointCollections();
        PreloadPointEntity.PointCollections.Count());
        fetchedRows += pagesize;
    }
}


private static List<PointEntity> ReadPaged(int pagesize, int fetchedRows)
{
    DataModel dataContext = InstantiateDataModel();
    var Points = (from p in dataContext.PointDatas
                select p.ToEntity());

    return Points.Skip(fetchedRows).Take(pagesize).ToList();
}

メモリを使い果たして、後で再利用したり解放したりしていないのはLinq2Sqlコードだと思いますが、メモリフットプリントを減らすにはどうすればよいですか?

私は、データをフェッチするために、エンティティのリストにデータを格納する場合の10倍のメモリを使用することを確認しました。ガベージコレクターを呼び出すことを検討しましたが、むしろ避けたいと思います。

4

1 に答える 1

2

取得するデータが多すぎてメモリに保存しているため、OOM例外が発生します。

2つの事柄のうちの1つが発生しています:

  1. ユーザーが結果のサブセットのみを表示する場合、および/またはこれがデータの「キャッシュ」の最初の試みである場合に、過剰な量のデータをロードしています。
  2. このすべてのデータが必要ですが、データにアクセスするために間違ったテクノロジー(Linq2Sql)を使用しています。

それが最初の場合は、次のいずれかを行う必要があります

  1. データの小さなチャンクをロードします(50Kまたはすべてではなく、20〜50レコード)
  2. これが表示のみを目的としている場合は、エンティティ自体ではなく、必要なものの予測を照会します。

大量のデータを管理するように設計されたETLツールを使用するよりも2番目の場合。Rhino.ETLが好きですが、SSISも機能します。

于 2012-06-21T10:57:24.070 に答える