<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TechTips &#187; Gerenciamento de Memória</title>
	<atom:link href="http://www.techtips.com.br/category/programacao/gerenciamento-de-memoria/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.techtips.com.br</link>
	<description>Dicas de Tecnologia</description>
	<lastBuildDate>Wed, 24 Jun 2009 19:06:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Gerenciador de Tarefas, e Uso de Mem&#243;ria no FireFox</title>
		<link>http://www.techtips.com.br/programacao/gerenciamento-de-memoria/gerenciador-de-tarefas-e-uso-de-memoria-no-firefox/</link>
		<comments>http://www.techtips.com.br/programacao/gerenciamento-de-memoria/gerenciador-de-tarefas-e-uso-de-memoria-no-firefox/#comments</comments>
		<pubDate>Wed, 21 Mar 2007 20:01:45 +0000</pubDate>
		<dc:creator>Leonel Togniolli</dc:creator>
				<category><![CDATA[Gerenciamento de Memória]]></category>

		<guid isPermaLink="false">http://www.techtips.com.br/programacao/gerenciamento-de-memoria/gerenciador-de-tarefas-e-uso-de-memoria-no-firefox/</guid>
		<description><![CDATA[Vendo uma &#8220;dica&#8221; sobre como fazer o Firefox utilizar menos memória, mais uma vez me surprendo como as pessoas não entendem como o Windows gerencia memória, se confundem com o números dados pelo gerenciador de tarefas e tomam decisões que acabam diminuindo a performance de seu sistema. Para começar, quero deixar bem claro um ponto: [...]]]></description>
			<content:encoded><![CDATA[<p>Vendo uma &#8220;dica&#8221; sobre como fazer o Firefox <a href="http://www.leandromerces.org/blog/2006/09/23/configtrim_on_minimize/">utilizar menos memória</a>, mais uma vez me surprendo como as pessoas não entendem como o Windows gerencia memória, se confundem com o números dados pelo gerenciador de tarefas e tomam decisões que acabam diminuindo a performance de seu sistema.</p>
<p>Para começar, quero deixar bem claro um ponto: não utilize o Gerenciador de Tarefas, em hipótese alguma, para falar sobre memória. Ele não diz quanto de memória é usada pela sua aplicação, não serve pra determinar se alguém está vazando memória, nem mesmo se uma aplicação utiliza mais memória que a outra.</p>
<p>A informação que é passada na coluna de uso de memória, no gerenciador de tarefas, é o <a href="http://support.microsoft.com/kb/108449/en-us">Working Set</a>. Working Set de um processo é o conjunto de páginas de memória fisica atualmente reservadas para este processo. Se a memória que sua aplicação está usando é menor que o Working Set, páginas livres estão disponíveis para atender requisições de alocação de memória rapidamente. Se sua aplicação utiliza mais memória que o Working Set reservado pra ela, parte dessa memória é jogada para o cache em disco &#8211; chamado de arquivo de troca, ou swap file. Além disso, o Working Set também soma o tamanho de DLLs carregadas, inclusive as de sistema, mesmo que estejam sendo compartilhadas por vários processos. Memory Mapped Files também contam como páginas para o Working Set mesmo não utilizando um byte de memória.</p>
<p>O Windows geralmente mantém reservadas no Working Set mais páginas do que a aplicação utiliza no momento, para que aplicações façam menos swap e tenham uma performance melhor quando precisarem alocar mais memória. Afinal, memória não alocada é memória desperdiçada, e quando for necessário mais memória do que está livre fisicamente, os working sets são diminuídos conforme for necessário.</p>
<p>Além de quando o Windows tem pressão de memória, o Working Set de uma aplicação geralmente também é diminuído quando a aplicação é minimizada. É fácil fazer o teste: pegue uma aplicação que você está usando faz algum tempo, olhe o Working Set dela no gerenciador de tarefas, minimize essa aplicação e veja como o Working Set diminuiu. A aplicação utiliza a mesma quantidade de memória que utilizava antes de ser minimizada, mas agora possui menos memória reservada para ela (e corre risco maior de cair no swap se a memória fisica estiver curta).</p>
<p>Uma terceira forma de diminuir o Working Set de uma aplicação é chamar a API <strong>SetWorkingSetSize</strong>(); para zerar o Working Set de uma aplicação, tendo o mesmo efeito de minimizá-la. Apesar de o propósito útil da API seja reservar um Working Set maior que o atual para evitar constante swaping ao realocar memória frequentemente, muita gente utiliza a API para o contrário, muita vezes em um timer, para manter os números sua aplicação no Gerenciador de Tarefas bonitos e aparentemente baixos. O resultado prático disso é, obviamente, uma maior lentidão para alocar memória e maior proabilidade de sua aplicação entrar no swap.</p>
<p>A decisão de manter o working set quando minimizado está documentada em páginas e páginas de discussão no bug que corrigiu o <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=76831">demorado reínicio após um grande período de inatividade</a>. Um <a href="http://lxr.mozilla.org/mozilla/source/widget/src/windows/nsWindow.cpp#1467">comentário no código fonte do Firefox</a> diz que se alguém reclamar do uso de memória do Firefox quando minimizado, vai ter a discussão completa sobre o bug tatuada nas costas. Espero que, entendendo o que é o Working Set, você não corra esse risco.</p>
<p><center>&copy; <a href="http://www.techtips.com.br">TechTips</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://www.techtips.com.br/programacao/gerenciamento-de-memoria/gerenciador-de-tarefas-e-uso-de-memoria-no-firefox/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>FastMM e Delphi 2006</title>
		<link>http://www.techtips.com.br/programacao/fastmm-e-delphi-2006/</link>
		<comments>http://www.techtips.com.br/programacao/fastmm-e-delphi-2006/#comments</comments>
		<pubDate>Thu, 22 Feb 2007 16:06:39 +0000</pubDate>
		<dc:creator>Alexandre José</dc:creator>
				<category><![CDATA[Componentes]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Gerenciamento de Memória]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[Linguagem Delphi]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Práticas]]></category>

		<guid isPermaLink="false">http://www.techtips.com.br/programacao/fastmm-e-delphi-2006/</guid>
		<description><![CDATA[Continuando um tema anteriormente publicado, neste artigo vamos começar a detectar os vazamentos de memória (memory leaks) existentes em nossos aplicativos. (isso se existirem, é claro&#8230;) A partir do&#160;Delphi 2006 o gerenciador de memória padrão que acompanha o Delphi passa a ser o FastMM. Quem não trabalha com Delphi 2006 pode baixar o FastMM aqui. [...]]]></description>
			<content:encoded><![CDATA[<p>Continuando um tema anteriormente publicado, neste artigo vamos começar a detectar os vazamentos de memória (memory leaks) existentes em nossos aplicativos. (isso se existirem, é claro&#8230;)</p>
<p>A partir do&nbsp;Delphi 2006 o gerenciador de memória padrão que acompanha o Delphi passa a ser o FastMM. Quem não trabalha com Delphi 2006 pode baixar o FastMM <a href="http://sourceforge.net/project/showfiles.php?group_id=130631">aqui</a>.</p>
<p>Se você estiver começando agora a desenvolver com Delphi deve estar se perguntando: Tá, e dai? O que é memory leak?</p>
<p><strong>Memory leak é um objeto criado pela aplicação que não foi corretamente destruído.</strong></p>
<p>Você pode simular esta situação criando qualquer objeto no OnCreate do formulário principal da sua aplicação. Exemplo:</p>
<p>
<pre>procedure TForm1.FormCreate(Sender: TObject);
var
  lstVazamento : TStrings;
begin
  lstVazamento := TStringList.Create;
  try
    lstVazamento.Add('Linha 1');
    lstVazamento.Add('Linha 2');
    lstVazamento.Add('Linha 3');
  finally

  end;
end;</pre>
</p>
<p>Execute o aplicativo e feche-o. Você notará que não acontece nada! <img src='http://www.techtips.com.br/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Esse teste ridículo foi feito só para você ver como é comum ocorrerem problemas que resultem em&nbsp;vazamentos de memória (memory leaks)&nbsp;como a falta de atenção (nesse caso),&nbsp;a pressa, Control+C / Control+V entre alguns outros.</p>
<p>Agora insira esta linha logo após o begin da sua procedure:</p>
<p>ReportMemoryLeaksOnShutdown := True;</p>
<p>Deixando o código assim:</p>
<p>
<pre>procedure TForm1.FormCreate(Sender: TObject);
var
  lstVazamento : TStrings;
begin
  ReportMemoryLeaksOnShutdown := True;

  lstVazamento := TStringList.Create;
  try
    lstVazamento.Add('Linha 1');
    lstVazamento.Add('Linha 2');
    lstVazamento.Add('Linha 3');
  finally

  end;
end;</pre>
</p>
<p>Repita a operação e veja o que acontece após fechar o aplicativo:</p>
<p><img src="http://www.waveobjects.com.br/blog/img/FastMMeDelphi2006_60DB/ML0127.png"> </p>
<p>Veja que recebemos a notificação do TStringList que criamos e das 3 linhas que adicionamos (String x 3) a ele. A&nbsp;partir dai podemos começar a evitar esse tipo de erro na hora de desenvolvermos aplicativos.</p>
<p>Uma dica importante é você utilizar o&nbsp;bloco <strong>try&#8230;finally&#8230;end;</strong> sempre que criar um objeto dinamicamente. Isto evita que ocorra um erro no meio da execução e ele não seja destruído devidamente. Veja os dois exemplos:</p>
<p><u>Método não apropriado:</u></p>
<p>
<pre>procedure TForm1.FormCreate(Sender: TObject);
var
  lstVazamento : TStrings;
begin
  ReportMemoryLeaksOnShutdown := True;

  lstVazamento := TStringList.Create;
  lstVazamento.Add('Linha 1');
  lstVazamento.Add('Linha 2');
  lstVazamento.Add('Linha 3');
  lstVazamento.Free;
end;</pre>
</p>
<p><u>Método apropridado de utilização:</u></p>
<p>
<pre>procedure TForm1.FormCreate(Sender: TObject);
var
  lstVazamento : TStrings;
begin
  ReportMemoryLeaksOnShutdown := True;

  lstVazamento := TStringList.Create;
  try
    lstVazamento.Add('Linha 1');
    lstVazamento.Add('Linha 2');
    lstVazamento.Add('Linha 3');
  finally
    lstVazamento.Free;
  end;
end;</pre>
</p>
<p>Utilizando o bloco <strong>try&#8230;finally&#8230;end;</strong> mesmo que ocorra algum erro na execução do procedimento o objeto é destruído. Pelo método não apropriado lstVazamento não seria destruído caso ocorresse algum problema na execução da linha lstVazamento.Add(&#8216;Linha 1&#8242;);, por exemplo.</p>
<p>Em tempo: utilizando ReportMemoryLeaksOnShutdown := True; a mensagem ocorrerá sempre que o aplicativo for terminado, inclusive fora do Delphi. Para evitarmos esse situação, substitua o True por DebugHook &lt;&gt; 0; deixando a linha assim:</p>
<p>ReportMemoryLeaksOnShutdown := DebugHook &lt;&gt; 0; </p>
<p>Para quem utiliza outras versões do Delphi isto deve ser configurado no arquivo FastMM4Options.inc.</p>
<p>No&nbsp;próximo artigo abordaremos mais funções do FastMM&nbsp;e configurações do arquivo FastMM4Options.inc para quem utiliza FastMM em versões mais antigas do Delphi. Até mais!</p>
<p><center>&copy; <a href="http://www.waveobjects.com.br/blog">TechTips</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://www.techtips.com.br/programacao/fastmm-e-delphi-2006/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Quanto de mem&#243;ria estou utilizando?</title>
		<link>http://www.techtips.com.br/programacao/entendendo-o-gerenciamento-de-memria/</link>
		<comments>http://www.techtips.com.br/programacao/entendendo-o-gerenciamento-de-memria/#comments</comments>
		<pubDate>Fri, 26 Jan 2007 12:49:41 +0000</pubDate>
		<dc:creator>Alexandre José</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Gerenciamento de Memória]]></category>
		<category><![CDATA[Linguagem Delphi]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Programação]]></category>

		<guid isPermaLink="false">http://www.techtips.com.br/programacao/entendendo-o-gerenciamento-de-memria/</guid>
		<description><![CDATA[É comum muitos programadores, inclusive eu, há&#160;algum tempo&#160;atrás,&#160;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 [...]]]></description>
			<content:encoded><![CDATA[<p>É comum muitos programadores, inclusive eu, há&nbsp;algum tempo&nbsp;atrás,&nbsp;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.</p>
<p>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).</p>
<p>A causa desse problema com o gerenciador de tarefas é&nbsp;o gerenciador de memória&nbsp;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. </p>
<p>Deste ponto de vista o bloco é a menor quantidade de bytes que o gerenciador aloca.</p>
<p>Exemplo:&nbsp;Um bloco tem 16 bytes; se o programa pede 4 bytes, o gerenciador irá alocar um bloco; se o programa pedir&nbsp;18 bytes, o gerenciador irá alocar dois blocos.</p>
<p>Parece que o gerenciador está &#8220;torrando&#8221; 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.</p>
<p>Entendendo melhor o funcionamento:</p>
<p>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.</p>
<p><strong>BINGO!</strong> Por isso que quando eu fazia debug da minha aplicação com o gerenciador de tarefas aberto os &#8220;Free&#8221; e &#8220;FreeAndNil&#8221; quase nunca funcionavam! <img src='http://www.techtips.com.br/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>No meu próximo post falarei sobre gerenciadores de memória alternativos como o FastMM,&nbsp;adotado como gerenciador de memória padrão na versão 2006 do Delphi,&nbsp;e faremos alguns testes comparativos. Até a próxima.</p>
<p><center>&copy; <a href="http://www.waveobjects.com.br/blog">TechTips</a></center></p>]]></content:encoded>
			<wfw:commentRss>http://www.techtips.com.br/programacao/entendendo-o-gerenciamento-de-memria/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.392 seconds -->

