Quanto de memória estou utilizando?
É comum muitos programadores, inclusive eu, há algum tempo atrás, medirem o consumo de memória de uma aplicação pelo gerenciador de tarefas do windows, o que é, na melhor das hipóteses, uma maneira incompleta de realizar essa verificação. O gerenciador de tarefas na verdade mostra a quantidade de memória que ele alocou naquele momento e não o quanto de memória o programa utiliza, além do que, o Windows contabiliza a memória alocada que foi utilizada e liberada até que outro programa a utilize.
Exemplo: seu programa utilizou 4.569K e liberou 169K, esse valor é contabilizado pelo windows até que outro programa o utilize (o gerenciador continua mostrando os 4.569K).
A causa desse problema com o gerenciador de tarefas é o gerenciador de memória runtime do Delphi alocar memória indiretamente. Quando o programa solicita memória para o gerenciador, ele aloca blocos de memória para o programa. Os blocos tem tamanho fixo de modo que para cada pedido de memória o gerenciador aloca a quantidade necessária de blocos contínuos para satisfazer o pedido do programa.
Deste ponto de vista o bloco é a menor quantidade de bytes que o gerenciador aloca.
Exemplo: Um bloco tem 16 bytes; se o programa pede 4 bytes, o gerenciador irá alocar um bloco; se o programa pedir 18 bytes, o gerenciador irá alocar dois blocos.
Parece que o gerenciador está “torrando” memória a toa, mas isso é feito para evitar a fragmentação da memória. Quando o programa devolve memória ao gerenciador, este não a devolve para o Windows, pois ele deduz que o programa pode solicitar mais memória a qualquer momento e a reserva para otimizar o tempo de acesso a ela.
Entendendo melhor o funcionamento:
Imagine que você possui duas classes (TAlocaMemoriaAtoa e TAlocaMemoriaAVontade). Quando executamos um programa qualquer, por exemplo, vamos imaginar que o gerenciador aloque 10 blocos de memória. Após isso criamos a classe TAlocaMemoriaAtoa que solicita ao gerenciador mais 10 blocos. O tamanho total de memória utilizada é 20 blocos. Ao destruírmos a classe TAlocaMemoriaAtoa o sistema libera 10 blocos, mas o gerenciador os mantém disponíveis para a aplicação. Se nesse momento criarmos a classe TAlocaMemoriaAVontade e esta solicita 5 blocos de memória, o gerenciador buscará 5 blocos dos 10 reservados anteriormente, quando a classe TAlocaMemoriaAtoa fora destruída.
BINGO! Por isso que quando eu fazia debug da minha aplicação com o gerenciador de tarefas aberto os “Free” e “FreeAndNil” quase nunca funcionavam!
No meu próximo post falarei sobre gerenciadores de memória alternativos como o FastMM, adotado como gerenciador de memória padrão na versão 2006 do Delphi, e faremos alguns testes comparativos. Até a próxima.




