DESALOCAR MEMORIA VB.NET

ICHIHARA 08/03/2017 11:23:54
#472271
Bom dia,

Estou com um problema em um processamento onde :

Dim Reg as List

do

Resg = db.tabela.Where(Function(x) x.campo1 = x _
And x.campo= True _
).ToList()
.
.
.
registro.clear()
Loop



O meu problema é que a cada loop o a memória vai aumentando até exibir outofmemory...
já tentei dar registro = nothing
GC.Collect()
GC.WaitForPendingFinalizers()

Mas a memória não baixa...

Alguém já passou por isto?


Alguma sugestão?

KERPLUNK 08/03/2017 14:37:10
#472281
Amigo, tenho quase certeza que você está fazendo de uma maneira muito pouco otimizada. O que você quer fazer exatamente?
ICHIHARA 08/03/2017 14:48:21
#472283
Boa Tarde Kerplunk,

Trata-se de um sistema existente que começou apresentar problemas de out of memory devido aumento da quantidade de registros apresentadas.
Ele efetua leitura via entity framework e faz a gravação em .txt.

Modifiquei o sistema para efetuar as leitura dos registros via datareader. funcionou perfeito e o consumo de memória foi mínimo.

Se tiver alguma dica, pois não gostaria de alterar a consulta via entity, gostaria de saber uma maneira de [Ô]desalocar[Ô] este list que não sai da memoria cada vez que é alimentado.


realmente no código acima esta ruim mesmo... esta fazendo uma consulta a cada loop...

do

Resg = db.tabela.Where(Function(x) x.campo1 = x _
And x.campo= True _
).ToList()
.
.
.
for each reg in Resg
grava txt
next
registro.clear()
Loop

O loop em si executa umas 5 vezes. O for each que retorna bastante registro


Obrigado!
KERPLUNK 08/03/2017 15:13:23
#472285
Certo. E o que deve se transformar? Tipo, o que vai ser gravado no TXT, que formato?
ICHIHARA 08/03/2017 15:38:34
#472287
O txt gerado é de tamanho fixo, sendo que não preciso formatar ele pois o retorno da consulta já traz tudo formatado certinho.
uso um stringbuilder pra concatenar os campos [Ô]nome[Ô] [Ô]telefone[Ô] etc

e gravo em um arquivo via streamwriter.

a parte de gravar no txt esta bacana. O problema é a List que mesmo eu colocando nothing não sai da memória.
KERPLUNK 08/03/2017 16:06:21
#472291
A lista que você cria com o método [Ô]Where[Ô] é oriunda de uma instância de contexto de dados(no seu caso Entity Framework). Ela ficará na memória enquanto o Entity Framework estiver inicializado. Se você está instanciando [Ô]db[Ô] no construtor do formulário, as variáveis oriundas dele só serão disponibilizadas para o GAC quando [Ô]db[Ô] for descartado. Por isso, sempre use os blocos [Ô]using[Ô], ainda mais para contexto da dados.
DS2T 08/03/2017 16:14:46
#472292
Resposta escolhida
Citação:


A lista que você cria com o método [Ô]Where[Ô] é oriunda de uma instância de contexto de dados(no seu caso Entity Framework). Ela ficará na memória enquanto o Entity Framework estiver inicializado. Se você está instanciando [Ô]db[Ô] no construtor do formulário, as variáveis oriundas dele só serão disponibilizadas para o GAC quando [Ô]db[Ô] for descartado. Por isso, sempre use os blocos [Ô]using[Ô], ainda mais para contexto da dados.



Complementando:
Mas para você não ficar abrindo e fechando seu contexto de dados a cada loop, você pode usar o método AsNoTracking. Ele não anexa o objeto na memória do contexto, ele apenas retorna as entidades da consulta. Isso deve resolver seu problema.

Obs: O AsNoTracking deve ser usado apenas quando você não precisa fazer um update nos seus dados de retorno.

Abraço!
ICHIHARA 08/03/2017 16:25:37
#472294
Kerplunk e DS2T

Muito Obrigado Pelas dicas!
Vou aplicar aqui!
ICHIHARA 08/03/2017 16:45:10
#472296
DS2T Adicionei

Resg = db.tabela.AsNoTracking.Where(Function(x) x.campo1 = x _
And x.campo= True _
).ToList()


Problema resolvido

Muito Obrigado!
DAMASCENO.CESAR 08/03/2017 16:52:33
#472297
ICHIHARA, se sua dúvida foi resolvida, encerre o tópico e pontue quem mais lhe auxiliou a sanar a dúvida
Tópico encerrado , respostas não são mais permitidas