Pergunta

Eu escrevi C ++ por 10 anos. I encontrou problemas de memória, mas eles poderiam ser corrigidos com uma quantidade razoável de esforço.

Para o último par de anos eu tenho escrito C #. Eu acho que eu ainda obter lotes de problemas de memória. Eles são difíceis de diagnosticar e correção devido à não-determinancy, e porque o C # filosofia é que você não deve ter que se preocupar com essas coisas quando você muito definitivamente fazer.

Um particular achado problema que é que eu tenho que descartar explicitamente e tudo de limpeza no código. Se eu não fizer isso, então os perfis de memória realmente não ajuda, porque há muito joio flutuando sobre você não consegue encontrar um vazamento de dentro de todos os dados que eles estão tentando mostrar-lhe. Pergunto-me se eu tenho a ideia errada, ou se a ferramenta que eu tenho não é o melhor.

Que tipo de estratégias e ferramentas são úteis para combater vazamentos de memória no .NET?

Foi útil?

Solução

Eu uso da Scitech MemProfiler quando suspeitar de um vazamento de memória.

Até agora, eu encontrei-o para ser muito confiável e potente. Ele já salvou minha bacon em pelo menos uma ocasião.

O GC funciona muito bem em .NET IMO, mas como qualquer outra linguagem ou plataforma, se você escrever código ruim, coisas ruins acontecem.

Outras dicas

Apenas para o problema esquecimento-to-dispor, tente o solução descrita neste blog . Aqui está a essência:

    public void Dispose ()
    {
        // Dispose logic here ...

        // It's a bad error if someone forgets to call Dispose,
        // so in Debug builds, we put a finalizer in to detect
        // the error. If Dispose is called, we suppress the
        // finalizer.
#if DEBUG
        GC.SuppressFinalize(this);
#endif
    }

#if DEBUG
    ~TimedLock()
    {
        // If this finalizer runs, someone somewhere failed to
        // call Dispose, which means we've failed to leave
        // a monitor!
        System.Diagnostics.Debug.Fail("Undisposed lock");
    }
#endif

Nós usamos Formigas Profiler Pro por software Red Gate em nosso projeto. Ele funciona muito bem para todas as aplicações baseadas na linguagem .NET.

Nós descobrimos que o .NET Garbage Collector é muito "seguro" em sua limpeza de objetos na memória (como deveria ser). Ele iria manter objetos ao redor apenas porque nós força usá-lo em algum momento no futuro. Isto significava que precisava ser mais cuidadoso sobre o número de objetos que nós inflado na memória. No final, nós convertemos todo o nosso objetos de dados sobre a uma "inflar on-demand" (pouco antes de um campo é solicitada), a fim de reduzir a sobrecarga de memória e aumentar o desempenho.

EDIT: Aqui está mais uma explicação sobre o que quero dizer com "inflar na demanda." Em nosso modelo de objeto de nosso banco de dados usar propriedades de um objeto pai para expor o objeto (s) filho. Por exemplo, se tivéssemos algum registro que referenciou algum outro "detalhe" ou registro "pesquisa" em uma base one-to-one teríamos estruturá-lo como este:

class ParentObject
   Private mRelatedObject as New CRelatedObject
   public Readonly property RelatedObject() as CRelatedObject
      get
         mRelatedObject.getWithID(RelatedObjectID)
         return mRelatedObject
      end get
   end property
End class

Nós descobrimos que o sistema acima criou alguns problemas de memória real e desempenho quando havia um monte de registros na memória. Portanto, transferido para um sistema onde os objetos só foram inflados quando foram solicitadas e chamadas de banco de dados foram feitas somente quando necessário:

class ParentObject
   Private mRelatedObject as CRelatedObject
   Public ReadOnly Property RelatedObject() as CRelatedObject
      Get
         If mRelatedObject is Nothing
            mRelatedObject = New CRelatedObject
         End If
         If mRelatedObject.isEmptyObject
            mRelatedObject.getWithID(RelatedObjectID)
         End If
         return mRelatedObject
      end get
   end Property
end class

Este acabou por ser muito mais eficiente porque os objetos foram mantidos sem memória até que eles eram necessários (o método Get foi acessado). É fornecido um grande aumento de performance em limitar acessos de banco de dados e um enorme ganho em espaço de memória.

Você ainda precisa se preocupar com a memória quando você está escrevendo código gerenciado a menos que sua aplicação é trivial. Vou sugerir duas coisas: em primeiro lugar, leia CLR via C # , porque ele vai ajudar você a entender o gerenciamento de memória no .NET. Em segundo lugar, aprender a usar uma ferramenta como o CLRProfiler (Microsoft). Isto pode lhe dar uma idéia do que está causando sua perda de memória (por exemplo, você pode dar uma olhada em sua grande fragmentação objeto pilha)

Você está usando código não gerenciado? Se você não estiver usando código não gerenciado, segundo a Microsoft, vazamentos de memória no sentido tradicional não são possíveis.

Memória usada por um aplicativo não pode ser liberada no entanto, para a alocação de memória de um aplicativo pode crescer ao longo da vida da aplicação.

A partir Como identificar vazamentos de memória no tempo de execução de linguagem comum no Microsoft.com

Um vazamento de memória pode ocorrer em um .NET Application Framework quando você usa código não gerenciado como parte do inscrição. Esta lata código não gerenciado Vazamento de memória, eo .NET Framework tempo de execução não pode resolver esse problema.

Além disso, um projeto só pode parecem ter um vazamento de memória. este condição pode ocorrer se muitos grandes objectos (tais como objectos DataTable) são declarados e, em seguida, adicionada a uma de recolha (tal como uma série de dados). o recursos que estes própria Maio objetos Nunca ser lançado, e os recursos são deixados vivos para todo o prazo de o programa. Este parece ser um vazar, mas na verdade é apenas um sintoma da maneira que a memória é sendo alocados no programa.

Para lidar com este tipo de problema, você pode implementar IDisposable. Se você quiser ver algumas das estratégias para lidar com o gerenciamento de memória, gostaria de sugerir procura de IDisposable, XNA, gerenciamento de memória como desenvolvedores de jogos precisa ter coleta de lixo mais previsível e por isso deve forçar o GC fazer a sua coisa.

Um erro comum é não remover manipuladores de eventos que subscrevem a um objeto. Uma assinatura manipulador de eventos vai impedir que um objeto seja reciclado. Além disso, dê uma olhada na usando declaração que permite criar um escopo limitado para a vida de um recurso.

Este blog tem algumas orientações realmente maravilhosas usando windbg e outras ferramentas para rastrear vazamentos de memória de todos os tipos. Excelente leitura para desenvolver suas habilidades.

Eu só tinha um vazamento de memória em um serviço do Windows, que eu fixo.

Em primeiro lugar, eu tentei MemProfiler . Eu achei muito difícil de usar e não é de todo fácil de usar.

Então, eu usei JustTrace que é mais fácil de usar e dá mais detalhes sobre os objetos que não estão dispostos corretamente.

Isso me permitiu resolver o vazamento de memória com muita facilidade.

Se os vazamentos que você está observando são devido a uma implementação de cache fugitivo, este é um cenário onde você pode considerar o uso de WeakReference. Isto poderia ajudar a garantir que a memória é liberada quando necessário.

No entanto, IMHO, seria melhor para considerar um bespoke solução -. Só você realmente sabe quanto tempo você precisa para manter os objetos em volta, para desenvolver código de limpeza adequado à sua situação é geralmente a melhor abordagem

Big Guns - Depuração Tools for Windows

Esta é uma incrível coleção de ferramentas. Você pode analisar ambos os montes gerenciados e não gerenciados com ele e você pode fazê-lo offline. Isso foi muito útil para depurar uma das nossas aplicações ASP.NET que manteve reciclagem devido ao uso excessivo de memória. Eu só tive que criar um despejo de memória cheia de processo de viver em execução no servidor de produção, toda a análise foi feita offline no WinDbg. (Descobriu-se algum desenvolvedor foi o uso excessivo de armazenamento de sessão na memória.)

"Se quebrado que é ..." blogue tem artigos muito úteis no o assunto.

A melhor coisa a ter em mente é manter o controle das referências a seus objetos. É muito fácil acabar com suspensão referências a objetos que você não se preocupam mais. Se você não vai usar algo mais, se livrar dele.

Acostume-se ao uso de um provedor de cache com vencimentos de correr, de modo que se algo não é referenciado para uma janela de tempo desejado, ele é dereferenced e limpo. Mas se ele estiver sendo acessado um monte ele vai dizer na memória.

Uma das melhores ferramentas está usando o Ferramentas de depuração para Windows , e tendo um despejo de memória do processo usando adplus , em seguida, usar windbg e sos plugin para analisar a memória do processo, fios e pilhas de chamadas.

Você pode usar esse método para a identificação de problemas em servidores também, depois de instalar as ferramentas, compartilhar o diretório, em seguida, ligar à partilha do servidor usando (uso líquido) e tomar um acidente ou pendurar despejo do processo.

Em seguida, analisar offline.

Depois de uma das minhas correções para aplicativo gerenciado tive a mesma coisa, como forma de verificar se a minha candidatura não terá o mesmo vazamento de memória após a minha próxima mudança, então eu escrevi algo como objeto quadro Verificação lançamento, visite um olhar sobre o pacote NuGet ObjectReleaseVerification . Você pode encontrar uma amostra aqui https://github.com/outcoldman/OutcoldSolutions-ObjectReleaseVerification-Sample, e informações sobre este exemplo http://outcoldman.ru/en/blog/show/322

Eu prefiro dotmemory da JetBrains

De Visual Studio 2015 considerar a utilização fora da caixa ferramenta de diagnóstico uso da memória para coletar e analisar os dados de uso de memória.

A ferramenta de uso da memória permite que você leve um ou mais instantâneos do heap de memória gerenciado e nativo para ajudar a entender o impacto o uso de memória de tipos de objetos.

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