Dicas sobre como lidar com grandes cordas com relação ao uso da memória
-
19-09-2019 - |
Pergunta
Como posso forçar um psiquiatra de um DataTable e / ou Lista para que eu possa liberar memória de forma eficiente? Estou neste momento a remoção da linha processada do DataSet cada iteração do loop, mas eu não tenho certeza se a memória está sendo liberado.
for (int i = m_TotalNumberOfLocalRows - 1; i >= 0; i--)
{
dr = dt.Rows[i];
// Do stuff
dt.Rows.Remove(dr);
}
Se isto não encolher a pegada do DataTable na memória posso usar um List. Eu só estou usando o DataTable como uma loja para os DataRows, eu poderia usar qualquer coleção ou mecanismo de armazenamento que seria pouca memória e ser capaz de liberar memória a cada x iterações.
Obrigado.
Editar: Depois de fazer um pouco de memória de perfil depois de ler Quais são alguns bons .NET Profilers? I 've descobriu que o principal consumidor de memória são strings.
Estamos fazendo muita saída do usuário durante o processo, e o consumo de memória é o ciclismo entre aproximadamente 170MB-230MB, chegando a cerca de 300MB. Eu estou usando um StringBuilder com um tamanho inicial de 20971520 para segurar a saída / log do que está acontecendo e depois de um por cento do número total de registros foram processados ??eu estou definindo a propriedade de texto de um controle DevExpress MemoEdit ao StringBuilder.ToString (). Descobri que este método é mais rápido do que anexando o StringBuilder.ToString () para o MemoEdit.Text (obviamente a lógica w.r.t. o StringBuilder é diferente entre anexando e definindo o MemoEdit.Text)
Eu também descobri que em vez de recriar o StringBuilder (20971520) é mais fácil na memória e mais rápido para executar apenas StringBuilder.Remove(0, StringBuilder.Length)
Existem algumas dicas que você poderia compartilhar para melhorar o desempenho ao trabalhar com grandes cadeias (o arquivo de log que escrito que contém o log é de aproximadamente 12.2MB por cerca de 30 000 registos)?
Nota: eu mudei o título da pergunta e as tags
.
título antigo:? Como eu posso obrigar um psiquiatra de um DataTable e / ou uma lista para memória lançamento
etiquetas velhos: lista de tabela de dados c # .net memória
Solução
Tente forçar um passe coletor de lixo:
GC.Collect();
Se você quer ter a certeza, que todos os objetos são finalizados antes de sua execução de código continua, chamada
GC.WaitForPendingFinalizers();
logo após GC.Collect ()
EDIT: Como as pessoas mencionadas nos comentários abaixo, é amplamente considerado uma má prática para chamar o coletor de lixo diretamente. No entanto, este representativo atingir o objetivo de liberar a memória unnused de suas linhas eliminadas.
Outras dicas
A menos que você está tendo um problema com a memória, não tente libertá-lo manualmente chamando o coletor de lixo. O tempo de execução vai lidar com isso para você e 99% do tempo ser mais eficiente no que faz que você vai tentando adivinhar quando o tempo ideal é.
O que você tem que lembrar é que quando você chamar GC.Collect (), corre contra todos os níveis da Coleta de Lixo e "arruma" todos os objetos que precisam necessidade de ser libertados. Você provavelmente irá ser passar o tempo do processador etc. manipulação algo que não precisa ser feito naquele momento.
Se você absolutamente tem que o comando é GC.Collect()
http://msdn.microsoft.com/en-us/library /xe0c2357.aspx
http://www.developer.com/net/csharp/article.php/3343191/C-Tip-Forcing-Garbage-Collection-in-NET.htm
Vara à tabela de dados e remover linhas desnecessárias como no seu exemplo.
Ao fazer isso o uso de memória você não pode controlar: isto é feito pelo Garbage Collector CLR.
Você tem uma necessidade explícita para gerenciar isso diretamente? O coletor de lixo consegue isso por você.