Caçando EOutOfResources

Pergunta, questão:

Existe uma maneira fácil de obter uma lista detipos de recursos que vazam em um aplicativo em execução? IOW conectando-se a um aplicativo?

Eu sei que a prova de memórias pode fazer isso, mas diminui a velocidade tanto que o aplicativo não dura nem um minuto. A maioria dos gostos de gerenciadores de tarefas pode mostrar o número, mas não o tipo.

Não é um problema que a verificação em si seja catastrófica (interrompe o processo do aplicativo), pois posso verificar com um taskmgr se estou chegando perto (ou pelo menos espero)

Quaisquer outros insights sobre a busca de vazamentos de recursos (não a memória) também são bem-vindos.

Fundo:

Eu tenho um aplicativo Delphi 7/2006/2009 (compila com todos os três) e depois de algumas semanas ele começa a agir de maneira engraçada. No entanto, apenas em um dos locais em que é executado, em vários outros sistemas, é executado até que a energia acabe.

Eu tentei colocar algum código de depuração para diminuir o problema. e descobriu que a exceção é EOutofResources ao salvar um arquivo. (o salvamento do arquivo pode acontecer milhares de vezes por dia).

Tentei raciocinar vazamentos de memória (com fastmm), mas como o fluxo de dados é bastante alto (60 MByte / s das câmeras industriais de gigabit), só posso descartar vazamentos de memória "rastejantes" com fastmm, não flashes rápidos de slots de memória que esgotam memória na hora em que isso acontece. Se algo der errado, o aplicativo preencherá a memória em menos de meio minuto.,

Os principais suspeitos são identificadores de arquivos que, de alguma forma, são deixados com algum erro e TMetafiles (que são transmitidos para esses arquivos). Os suspeitos menores são VST, popupmenu e tframes

Atualizações:

Outra dica possível: funcionou bem por dois anos com o D7 e agora os problemas estão no Turbo Explorer (que eu uso em projetos estáveis que não foram convertidos no D2009).

Paul-Jan: Como acontece apenas uma vez por semana (e isso pode acontecer à noite), a aquisição de informações é lenta. É por isso que faço essa pergunta, preciso combinar coisas para quando eu estiver na quinta-feira. Em resumo: não, não sei 100% de certeza. Pretendo trazer toda a coleção Systemtools para ver se consigo encontrar alguma coisa (porque ela estará em execução por dias). Há também uma chance de eu ver arquivos abertos. (talvez deva tentar encontrar algumas dicas e agendá-lo)

Mas o aplicativo vê muito pouca ação da GUI (é um aplicativo de inspeção de visão de máquina), exceto a atualização de tela +/- 15 / s, que é tbitmap stretchdraw + tmetafile, mas recebo esse erro ao salvar os identificadores de disco (TFileStream) provavelmenterealmente Exausta. No entanto, no mesmo fluxo, o TMetafile também é transmitido por savet, algo que os aplicativos posteriores não possuem mais e podem ser executados a partir de meses.

------------------- ATUALIZAÇÃO

Eu procurei, procurei e procurei, e consegui reproduzir os problemas in vitro duas ou três vezes. Os problemas ocorreram quando a memória foi de +/- 256 MB (os sistemas têm 2 GB), objetos de usuário 200, objetos de gdi 500, nenhum arquivo mais aberto do que o esperado).

Isso não é realmente excepcional. Percebo que vazo pequenas quantidades de identificadores, provavelmente devido a quadros de reparação (algo no VCL parece vazar no HPalette), mas suspeito que a causa principal seja um problema diferente. Eu reutilizo o TMetafile e o limpo entre eles. Eu acho que limpar o metarquivo não redimensiona (sempre?) O recurso, eventualmente cada metarquivo no pool inteiro de tmetafile no tamanho máximo e com 20-40 + tmetafiles (que podem ter vários 100ks cada), isso afetará a área de trabalho limite de pilha.

Essa é a teoria, mas tentarei verificar isso definindo o limite da área de trabalho para 10 MB nos clientes, mas levará várias semanas até que eu tenha confirmação se isso mudar alguma coisa. Essa teoria também confirma por que essa máquina é especial (é possível que ela naturalmente tenha metarquivos um pouco maiores, em média). Ocasionalmente, liberar e recriar um arquivo tmeta na piscina também pode ajudar.

Felizmente, todos esses problemas (tmetafile e reparenting) já foram projetados nas novas gerações dos aplicativos.

Devido às circunstâncias especiais (e ao fato de eu ter janelas de teste muito limitadas), isso vai demorar um pouco, mas decidi aceitar o heap da área de trabalho como um exemplo por enquanto (embora o material do GDILeaks também tenha sido útil).

Outra coisa que a auditoria revelou o uso dos tipos GDI em um encadeamento (apesar de salvar apenas tmetafiles (que não foram usados ou conectados de outra forma) aos fluxos.

------------- Atualização 2.

Aumentar o limite da área de trabalho parecia aumentar pouco o tempo até o problema ocorrer.

Infelizmente, não poderei continuar com isso, pois as máquinas foram atualizadas para uma versão mais nova da estrutura que não apresenta o problema.

Em resumo, só posso declarar o que as três principais modificações estavam passando da antiga para a nova estrutura:

Não altero mais as telas reparando quadros. Agora trabalho com formulários que oculto e mostro. Eu mudei isso, pois também tive falhas ou exceções muito raras (que podem ser clicadas) devido a isso. As falhas ocorreram durante a operação da GUI, embora não espontaneamente como o principal problemaA rotina em que ocorreu a falha tratou do TMetafile. O TMetafile foi projetado e substituído por um formato próprio mais simples. (basicamente matrizes com vértices Opengl)O desenho não aconteceu mais com o tbitmap com uma sobreposição tmetafile desenhada sobre ele, mas usando o OpenGL.

É claro que também poderia ser outra coisa, que foi alterada na reescrita das partes acima, corrigindo alguns erros de detalhes muito desagradáveis. Teria que ser extremamente ruim, pois analisei o sistema acima o máximo que pude.

Atualizado novembro de 2012 após uma discussão particular por correio: Em retrospecto, a próxima etapa seria adicionar um contador aos objetos de metarquivos e simplesmente restabelecê-los a cada x * 1000 mais ou menos e ver se isso muda alguma coisa. Se você tiver problemas semelhantes, tente verificar se é possível destruir e reinicializar regularmente recursos de longa vida que são alocados dinamicamente.

questionAnswers(7)

yourAnswerToTheQuestion