Pergunta

Eu tenho tido alguns problemas com LINQ to SQL em torno de uso de memória. Eu estou usando-o em um serviço do Windows para fazer algum processamento, e eu estou looping através de uma grande quantidade de dados que eu estou puxando para trás a partir do contexto. Sim - Eu sei que eu poderia fazer isso com um procedimento armazenado, mas há razões para que que seria um menos do que a solução ideal

.

De qualquer forma, o que eu vejo, basicamente, é a memória não está sendo liberado mesmo depois de eu chamar context.SubmitChanges(). Então eu acabar tendo que fazer todo tipo de coisas estranhas como apenas puxar para trás 100 registros no tempo, ou criar vários contextos e têm todos eles fazer tarefas separadas. Se eu manter o mesmo DataContext e usá-lo mais tarde para outras chamadas, ele só come-se mais e mais memória. Mesmo que eu chamo Clear() no array "var tableRows" que a consulta retorna para mim, defini-lo como nulo, e SYstem.GC.Collect() chamada -. Ainda não liberar a memória

Agora eu li alguns sobre como você deve usar DataContexts rápida e eliminá-los rapidamente, mas parece que a sua deveria ser uma maneira de forçar o contexto para despejar todos os seus dados (ou todos os seus dados de rastreamento para um determinado tabela) em um determinado ponto para garantir a memória está livre.

Alguém sabe quais os passos garantia de que a memória é liberada?

Foi útil?

Solução

Se você não precisa conjunto objeto tracking DataContext.ObjectTrackingEnabled false . Se você precisar fazer isso, você pode usar a reflexão para chamar o interno DataContext.ClearCache () , embora você tem que estar ciente de que desde a sua interno, sujeito a desaparecer em uma versão futura do quadro. E, tanto quanto eu posso dizer, o próprio quadro não usá-lo, mas ele faz limpar o cache de objetos.

Outras dicas

A DataContext rastreia todos os objetos que jamais obtida. Ele não vai liberar isso até que é lixo coletado. Além disso, como ele implementa IDisposable, você deve chamar Dispose ou usar a declaração using.

Este é o caminho certo a seguir:

using(DataContext myDC = new DataContext)
{
  //  Do stuff
} //DataContext is disposed

Como David Salienta, você deve descartar o DataContext usando um bloco usando.

Parece que a sua principal preocupação é sobre a criação e eliminação de um monte de objetos DataContext. Isto é como linq2sql é projetado. O DataContext destina-se a ter vida curta. Desde que você está puxando um monte de dados do DB, faz sentido que haverá um monte de uso de memória. Você está no caminho certo, através do processamento de seus dados em blocos.

Do not ter medo de criar uma tonelada de DataContexts. Eles são projetados para ser usado dessa forma.

Obrigado rapazes - Vou verificar o método ClearCache. Só para esclarecer (para futuros leitores), a situação em que eu estava começando a usuage memória era algo como isto:

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
   }
}

Eu só tive um problema similar. No meu caso, ajudou a estabelecer as propriedades de DataContext.ObjectTrackingEnabled para false. Mas ele só funciona no caso de iteração através das linhas da seguinte forma:

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

Se, por exemplo, na consulta para usar os métodos ToArray () ou ToList () - nenhum efeito

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top