Pergunta

Eu tenho um aplicativo WindowsForms que aparece a vazar memória, então eu usei ANTS Memória Profiler de Redgate de olhar para os objetos Eu suspeito e achar que eles só são ocupados por objetos já no Queue Finalizer . Grande, exatamente o que é uma Fila de Finalizer? você pode me aponte para a melhor definição? Você pode compartilhar qualquer conselho anedótica?

Além disso, todos os objetos do GC raiz na fila finalizador são instâncias de System.Windows.Forms.Control + ThreadMethodEntry objetos nomeados "chamador". Vejo que ele está envolvido em multi-thread interação UI, mas eu não sei muito além disso. Perdoe minha preguiça aparente e ignorância admitiu, mas esses recursos estão todos enterrados dentro do componente de um fornecedor. Eu estou falando com o fornecedor sobre estas questões, mas eu preciso de alguma direção para me até a velocidade na conversa. você pode me aponte para a definição mais útil de ThreadMethodEntry também? Algum conselho anedótica?

Além disso, eu deveria mesmo se preocupar com esses objetos no finalizador fila?

Update: Este artigo Red gate foi útil.

Foi útil?

Solução

A fila finalizador detém todos os objetos que têm um método finalizador definido. Lembre-se que um finalizador é um meio de recursos não gerenciados colecionam como alças. Quando o coletor de lixo coleta de lixo, ele se move todos os objetos com um finalizador para a fila finalizador. Em algum ponto later-- dependendo da pressão de memória, heurísticas GC, e a fase do moon-- quando o coletor de lixo decide recolher esses objetos, ele caminha pela fila e executa os finalizadores.

Tendo trabalhado com vazamentos de memória no passado, vendo um monte de objetos do seu fornecedor na fila finalizador poderia ser código desleixado, mas não indica um vazamento de memória. Normalmente, o código de bom vai expor um método Dispose que irá recolher os recursos gerenciados e não gerenciados, e ao fazê-lo, retire-se do finalizador fila via GC.SuppressFinalize(). Então, se os objetos do fornecedor fazer implementar um método Dispose, e seu código não chamá-lo, que poderia levar a um monte de objetos no finalizador fila.

Você tentou criar um instantâneo no ANTS entre dois pontos no tempo e comparando os objetos criados entre eles? Isso pode ajudá-lo a identificar quaisquer objetos gerenciados ser vazado.

Além disso, se você quiser ver se a memória desaparece quando os finalizadores são executados, tente isto apenas para teste com:

System.GC.Collect();
System.GC.WaitForPendingFinalizers(); // this method may block while it runs the finalizers
System.GC.Collect();

Eu não recomendo executar esse código normalmente. Você pode querer executá-lo se você acabou de fazer uma tonelada de trabalho e criou lotes de lixo. Por exemplo, em nosso aplicativo, uma das nossas funções pode criar cerca de 350 MB de lixo que vai para o lixo depois de fechar uma janela MDI. Uma vez que este é conhecido por deixar lotes de lixo, nós manualmente forçar a coleta de lixo.

Além disso, note que há um cache de propriedade de baixo nível no código Windows.Forms base que ficará com a última diálogo modal aberta. Esta poderia ser uma fonte de um vazamento de memória. Uma maneira de se livrar desta referência é forçar outra diálogo simples para aparecer, em seguida, executar o código acima GC.

Outras dicas

A fila finalizador é uma fila onde as instâncias de objetos que não são mais usados ??estão esperando para ser finalizado pelo GC. Todos os objetos neste fila será finalizado e seus vazamentos de memória provavelmente não vem de um desses queridos diretamente. Mas, um desses objetos não pode liberar todos os seus recursos não gerenciados.

A classe ThreadMethodEntry é uma implementações de IAsyncResult e instâncias desta classe são tipicamente criados ao invocar operações assíncronas, como o uso de Invoke para atualizar a interface do usuário ou usando Comece * / Fim * métodos.

Aqui está um bom post que descreve um problema semelhante. A um nível mais técnico, você pode olhar para usando SOS.dll (que o blog descreve) e Sosex.dll para ajudá-lo a trabalhar fora porque estes ThreadMethodEntry objetos são penduradas em torno na memória. Existem comandos nestas extensões WINDBG que podem rastrear o que os outros objetos estão fazendo referência a um objeto específico na memória.

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