Otimizando o uso de memória do seu programa Delphi

Ao escrever aplicativos de longa execução - o tipo de programa que passará a maior parte do dia minimizado na barra de tarefas ou bandeja do sistema, pode ser importante não deixar o programa "fugir" com o uso da memória.

As duas colunas mais à direita indicam o uso da CPU (tempo) e o uso da memória. Se um processo causar um impacto severo em qualquer um deles, seu sistema ficará lento.

O tipo de coisa que afeta freqüentemente o uso da CPU é um programa em loop (pergunte a qualquer programador que tenha esquecido de colocar uma instrução "read next" em um loop de processamento de arquivo). Esses tipos de problemas geralmente são facilmente corrigidos.

O uso de memória, por outro lado, nem sempre é aparente e precisa ser gerenciado mais do que corrigido. Suponha, por exemplo, que um programa do tipo captura esteja sendo executado.

Este programa é usado durante todo o dia, possivelmente para captura telefônica em um suporte técnico ou por algum outro motivo. Não faz sentido desligá-lo a cada vinte minutos e iniciá-lo novamente. Ele será usado ao longo do dia, embora em intervalos pouco frequentes.

instagram viewer

Se esse programa depende de algum processamento interno pesado ou possui muitas obras de arte em seus formulários, mais cedo ou mais tarde uso de memória vai crescer, deixando menos memória para outros processos mais frequentes, aumentando a atividade de paginação e, finalmente, diminuindo a velocidade do computador.

Digamos que você irá criar um programa com o formulário principal e dois adicionais (modais). Normalmente, dependendo da sua versão do Delphi, o Delphi irá inserir os formulários no diretório unidade de projeto (Arquivo DPR) e incluirá uma linha para criar todos os formulários na inicialização do aplicativo (Aplicativo. CreateForm (...)

As linhas incluídas na unidade do projeto são do Delphi e são ótimas para pessoas que não estão familiarizadas com o Delphi ou que estão apenas começando a usá-lo. É conveniente e útil. Isso também significa que TODOS os formulários serão criados quando o programa iniciar e NÃO quando forem necessários.

Dependendo do objetivo do seu projeto e da funcionalidade que você implementou, um formulário pode usar muita memória, portanto formulários (ou em geral: objetos) só devem ser criados quando necessários e destruídos (liberados) assim que não mais necessário.

Ambos, "DialogForm" e "OccasionalForm" precisam ser removidos da lista de "Criação automática de formulários" e movidos para a lista "Formulários disponíveis".

Observe que a estratégia descrita aqui é baseada na suposição de que o programa em questão é um programa do tipo "captura" em tempo real. No entanto, pode ser facilmente adaptado para processos do tipo lote.

Delphi tentou minimizar isso e tem sua própria arquitetura de gerenciamento de memória que usa blocos muito menores, mas isso é praticamente inútil no ambiente Windows, porque a alocação de memória acaba por ficar no sistema operacional.

Depois que o Windows aloca um bloco de memória para um processo, e esse processo libera 99,9% da memória, O Windows ainda perceberá que todo o bloco está em uso, mesmo que apenas um byte do bloco esteja realmente sendo usava. A boa notícia é que o Windows fornece um mecanismo para limpar esse problema. O shell nos fornece uma API chamada SetProcessWorkingSetSize. Aqui está a assinatura:

Por definição, a função SetProcessWorkingSetSize define os tamanhos mínimo e máximo do conjunto de trabalho para o processo especificado.

Esta API destina-se a permitir uma configuração de baixo nível dos limites mínimo e máximo de memória para o espaço de uso de memória do processo. No entanto, ele tem um pouco de peculiaridade, o que é muito afortunado.

Se os valores mínimo e máximo forem definidos como $ FFFFFFFF, a API cortará temporariamente o tamanho do conjunto para 0, trocando-o de memória e imediatamente como retorna à RAM, ele terá a quantidade mínima de memória alocada a ela (tudo isso acontece em alguns nanossegundos, portanto, para o usuário imperceptível).

Uma chamada para esta API será feita apenas em intervalos determinados - não continuamente, portanto, não haverá nenhum impacto no desempenho.

Agora, verifique periodicamente a última contagem de marcações em relação a "Agora" e se a diferença entre os dois for maior que o período considerado um período inativo seguro, apare a memória.

Agora decida depois de qual período de tempo você considerará o programa inativo. Decidimos dois minutos no meu caso, mas você pode escolher qualquer período que desejar, dependendo das circunstâncias.

Adaptar esse método a longos tempos de processamento ou processos em lote é bastante simples. Normalmente, você terá uma boa idéia de onde um processo demorado começará (por exemplo, início de um loop lendo milhões de registros do banco de dados) e onde ele terminará (final do loop de leitura do banco de dados).

Simplesmente desative seu cronômetro no início do processo e ative-o novamente no final do processo.

instagram story viewer