22

メモリ使用量に関して、LINQ-To-SQL でいくつかの問題が発生しています。Windows サービスで使用して何らかの処理を行っており、コンテキストから引き戻す大量のデータをループしています。はい - ストアド プロシージャを使用してこれを実行できることはわかっていますが、それが理想的なソリューションとは言えない理由があります。

とにかく、私が基本的に見ているのは、呼び出した後でもメモリが解放されていないことcontext.SubmitChanges()です。そのため、一度に 100 レコードだけをプルバックしたり、複数のコンテキストを作成してそれらすべてに個別のタスクを実行させたりするなど、あらゆる種類の奇妙なことをしなければならなくなります。同じままにしDataContextて後で他の呼び出しに使用すると、ますます多くのメモリが消費されます。Clear()クエリが返す" " 配列を呼び出しvar tableRows、null に設定して呼び出しSYstem.GC.Collect()ても、メモリは解放されません。

今、私はあなたDataContextsがそれらを素早く使用し、素早く処分する方法についていくつか読んだことがありますが、コンテキストにすべてのデータ(または特定のテーブルのすべての追跡データ)をメモリが空いていることを保証する特定のポイント。

メモリが解放されることを保証する手順を知っている人はいますか?

4

5 に答える 5

23

DataContextは、これまでにフェッチしたすべてのオブジェクトを追跡します。ガベージコレクションが行われるまで、これはリリースされません。また、を実装するため、ステートメントをIDisposable呼び出すDisposeか使用する必要があります。using

これが正しい方法です。

using(DataContext myDC = new DataContext)
{
  //  Do stuff
} //DataContext is disposed
于 2008-09-23T19:04:36.567 に答える
15

オブジェクトトラッキングが必要ない場合は、DataContext.ObjectTrackingEnabledfalseに設定します。必要な場合は、リフレクションを使用して内部DataContext.ClearCache()を呼び出すことができますが、内部であるため、フレームワークの将来のバージョンでなくなる可能性があることに注意する必要があります。そして、私が知る限り、フレームワーク自体はそれを使用しませんがオブジェクトキャッシュをクリアします。

于 2008-09-23T19:11:20.263 に答える
7

Amy が指摘するように、using ブロックを使用して DataContext を破棄する必要があります。

あなたの主な関心事は、一連の DataContext オブジェクトを作成して破棄することです。これが linq2sql の設計方法です。DataContext は、有効期間が短いことを意図しています。データベースから大量のデータを取得しているため、大量のメモリが使用されることは理にかなっています。データをチャンクで処理することで、正しい軌道に乗っています。

大量の DataContext を作成することを恐れないでください。それらはそのように使用されるように設計されています。

于 2008-09-23T19:25:09.123 に答える
3

みんなありがとう - ClearCache メソッドをチェックアウトします。(将来の読者のために)明確にするために、私がメモリ使用量を取得していた状況は次のようなものでした:

using(DataContext context = new DataContext())
{
   while(true)
   {
      int skipAmount = 0;
      var rows = context.tables.Select(x => x.Dept == "Dept").Skip(skipAmount).Take(100);

      //break out of loop when out of rows

      foreach(table t in rows)
      {
         //make changes to t   
      }

      context.SubmitChanges();
      skipAmount += rows.Count();

      rows.Clear();
      rows = null;

      //at this point, even though the rows have been cleared and changes have been
      //submitted, the context is still holding onto a reference somewhere to the
      //removed rows.  So unless you create a new context, memory usuage keeps on growing
   }
}
于 2008-09-24T14:40:08.940 に答える
0

私はちょうど同様の問題に遭遇しました。私の場合、 DataContext.ObjectTrackingEnabledのプロパティ を false に設定するのに役立ちました。ただし、次のように行を反復する場合にのみ機能します。

using (var db = new DataContext())
{
    db.ObjectTrackingEnabled = false;
    var documents = from d in db.GetTable<T>()
                     select d;
    foreach (var doc in documents)
    {
        ...
    }
}

たとえば、クエリでメソッド ToArray() または ToList() を使用する場合 - 効果なし

于 2016-09-16T11:51:35.450 に答える