Como funcionam os alocadores de memória do STD C?

Um pequeno artigo que explica por que seu programa jamais retorna memória ao sistema operacional enquanto está em execução.

[ Hits: 38.973 ]

Por: Ronaldo Faria Lima em 28/06/2004


O que é a lista livre?



As funções de alocação de memória podem requerer mais memória para o seu programa fazendo chamadas de sistema. Porém, existem situações em que estas funções não fazem nenhuma chamada de sistema. Mágica? Na verdade é a forma como foram implementadas: elas obtém a memória da lista livre.

O sistema de gerenciamento de memória implementado pela biblioteca standard C é bem interessante. As funções de alocação gerenciam uma lista de blocos que contém toda a memória alocada por elas. Sempre que eu programa solicita por uma arena de memória, seja chamando malloc, calloc ou realloc, as funções de alocação primeiro verificam a lista de memória livre, que é uma lista circular onde as funções colocam as arenas de memória que estão disponíveis para uso. Se a lista estiver vazia ou se não existirem blocos de memória suficientes para atender à solicitação do seu programa, as funções de alocação fazem uma chamada de sistema para obter mais memória do sistema operacional e, no caso se sucesso, colocam este novo bloco na lista de memória livre, marcam-na como em uso e devolvem um ponteiro para este bloco para o programa que fez a requisição.

Esta implementação tem um bom motivo: estatisticamente, seu programa tende a reutilizar memória. Ou seja, os blocos alocados dinamicamente têm tempo de vida curto e são disponibilizados novamente para uso futuro. Se a biblioteca Standard C não tivesse esse esquema, seu programa faria uma quantidade absurda de chamadas de sistema e o custo seria, basicamente, a degradação significativa da performance do seu programa.
Página anterior     Próxima página

Páginas do artigo
   1. Uma introdução ao sistema de alocação de memória do STD C
   2. Como funcionam os alocadores de memória?
   3. O que é a lista livre?
   4. O que acontece quando libero memória?
   5. Conclusão
Outros artigos deste autor

Escrevendo o caos em C

Programando com uma granada de mão: uma visão da linguagem C

Leitura recomendada

Sinais em Linux

GNA: um Coprocessador para Aceleração Neural

Mapear objetos em C

O Produtor e o Consumidor

Ponteiros - Saindo de Pesadelos

  
Comentários
[1] Comentário enviado por espinafre em 29/06/2004 - 11:28h

Bastante interessante... Eu havia notado um comportamento estranho no Apache: eu tinha um script PHP que necessitava de uma enormidade de memória (coisa de 200MB). Usando o gnome-system-monitor, vi o uso de memória do sistema crescer para mais de 400MB enquanto o programa executava (só o Apache, e portanto meu programa PHP, usava em torno de 300MB). Depois que o programa terminou, esses 300MB não foram liberados pelo sistema. Trem doido, sô!

[2] Comentário enviado por bogdano em 03/07/2004 - 21:54h

Muito interessante o artigo. Agradeço por compartilhar o seu conhecimento

[3] Comentário enviado por hilmilho em 02/12/2004 - 09:15h

Quanto aos 300MB que o espinafre falou se foi usada essa biblioteca mencionada no arquivo deveria ter liberado.

[4] Comentário enviado por nick_skyp em 16/01/2005 - 04:47h

realmente mto interessante!!
parabeins.. ms pintou uma duvida aki...
a STD C é implementada em C, certo?
ela usa "lista circular" para guardar areas de memoria(livres ou naum), ateh aeh blza... ms jah qdo se fala em lista, eu soh consigo pensar em alocação dinâmica... :-) naum sei se eh assim q funciona na STD C, ms essa lista na verdade tem tamanho limitado? (estatica)...
se naum, como eh que funciona o processo de "criação dos nós dessa 'lista livre' ?? (dinamica), senão atraves do sistema operacional ou pelo uso de seus proprios nós?? "
humm.. fikou confuso agora :S...

[5] Comentário enviado por ron_lima em 16/01/2005 - 08:50h

A lista livre nada mais é que uma lista encadeada. Sempre que as funções calloc, malloc ou realloc solicitam mais memória do sistema operacional, esta nova arena de memória é ligada à esta lista. Esta lista não tem limite e a quantidade de memória a ser alocada é limitada pelo sistema operacional.

Quando seu programa chama a função "free", na verdade a arena de memória passada como parâmetro volta à lista encadeada, onde é marcada como "disponível para realocação". Este comportamento tem uma vantagem em termos de performance, pois qualquer realocação de memória subseqüente não será realizada através de chamadas de sistema.

No caso do que o espinafre disse, o efeito é este mesmo: seu programa jamais vai liberar memória de volta para o sistema operacional. Por exemplo, se o seu programa tem um core de tamanho 10k e aloca mais 10k, ele ficará, durante toda sua execução, ocupando 20k de memória, mesmo que você chame a função free exaustivamente. Como dito no artigo, a função free não libera memória para o sistema operacional, mas a disponibiliza em uma lista encadeada interna à biblioteca STDC para realocação futura.

Como boa literatura sobre o assunto, um excelente livro é o do Kernighan e Ritchie - Linguagem C, onde apresentam um alocador de memória simples. Outro excelente livro é A Biblioteca Standard C, de P.J. Plauger que participou do X3J11.

[6] Comentário enviado por ron_lima em 16/01/2005 - 08:52h

Detalhando um pouco mais a lista... Quando a memória é solicitada ao sistema operacional, a biblioteca STDC aloca, na verdade, um pouquinho mais. Este "pouquinho" é para conter os pointers que serão usados para a ligação na lista livre.

[7] Comentário enviado por ron_lima em 16/01/2005 - 08:55h

Hilmilho, no caso do programa em PHP, realmente a memória não será liberada. O que ocorre é que o apache trabalha carregando módulos em seu espaço de endereçamento. Assim, o engine PHP será carregado dentro do espaço de endereçamento do apache. O que quer que o PHP aloque de memória ficará preso dentro do apache.

Existe uma forma de configurar isso, acredito eu, que é tornar o apache um servidor multi-processo. Assim, todas as solicitações que chegarem serão processadas por um processo filho que liberará tudo o que for alocado quando terminar.

Esta configuração torna o apache muito pesado pois é mais suave para o SO criar uma thread do que um processo inteiro. Sem falar que a criação de um processo inteiro provoca a duplicação de todo o address space do processo pai, o que é um senhor overhead.

[8] Comentário enviado por nick_skyp em 16/01/2005 - 17:14h

humm.. valeu explicou melhor.. qestao da lista agora...
na verdade em um caso bem particular.. esse "poukinho alocado a mais pelo STD C" pode resultar por exemplo em um MALLOC retornando NULL... certo!?? ^^

[9] Comentário enviado por ron_lima em 16/01/2005 - 22:00h

Não. Este pouquinho a mais usualmente não ultrapassa mais que 4 bytes, dependendo da plataforma (em plataformas de 64 bits, este valor chega a 8 bytes). Se bem que isso depende, muito, da implementação da libC que você esteja usando. Esta é uma estimativa. A implementação do lib STDC é extremamente dependente do sistema operacional. As interfaces são sempre as mesmas, mas a implementação difere consideravelmente .Por exemplo, chamadas de sistema em uma máquina linux são completamente diferentes das chamadas de sistema em uma máquina Solaris.

A família de alocação de memória do STDC (malloc, calloc e realloc) podem retornar um ponteiro nulo apenas quando não há mais como obter memória para retornar ao programa. Isso acontece da seguinte maneira: Seu programa requisita memória à biblioteca STDC, seja chamando malloc, calloc ou realloc. Estas funções, em um primeiro momento, irão tentar localizar uma arena de memória com o tamanho solicitado na lista livre. Caso não exista, estas funções vão solicitar memória ao sistema operacional. Porém, se o processo chegou a um determinado limite, seja por imposição do administrador do sistema em alguns sistemas, seja por que realmente não existe mais memória disponível para alocação, a chamada de sistema irá falhar. Esta falha é traduzida pelas funções como um ponteiro inválido, cujo valor é zero (a macro NULL expande para a constante 0, que pode ser long dependendo do sistema).

O que se precisa ter em mente é que a idéia dos alocadores de memória do STDC é isolar seu programa da interface do sistema operacional, tornando, assim, seu programa independente de plataforma. Se você programar para unix usando o STDC, é garantido que seu programa funciona em Windows, Windows CE, Palm OS, BeOS e por aí vai.

[10] Comentário enviado por nick_skyp em 17/01/2005 - 04:48h

certo... valeu pelos esclarecimentos... ms qeria q c respondesse(se puder)... a pergunta q fiz no artigo de "introdução as bibliotecas em C"..
ateh logo e parabeins pelos artigos!

[11] Comentário enviado por xguilhermex em 22/11/2005 - 15:02h

Valew fiko bem explicado...

[12] Comentário enviado por f_Candido em 05/01/2008 - 00:34h

Muito bem abordado. Parabéns. Pensava de forma diferente. Valeu.

[13] Comentário enviado por ryonagana em 10/11/2008 - 12:38h

confesso que nao manjo muito de alocação dinâmica em C
pulei essa aula na facul e aprendi sozinho a fazer isso com C++ (usando new e delete)

uhauhahua agora que peguei o gosto nao consigo voltar pro C =(

[14] Comentário enviado por ron_lima em 10/11/2008 - 18:44h

Os alocadores de memória do C++ funcionam exatamente da mesma maneira, ou seja, solicitam ao sistema operacional mais memória (caso do new) e devolvem a um pool interno no caso da desalocação (caso do delete). Da mesma maneira, o delete não devolve ao sistema operacional a memória alocada. A diferença básica é que estes operadores do C++ fazem um pouco mais do que apenas alocarem memória. No caso do new, ele também chama o construtor da sua classe e no caso do delete, o destrutor.

[15] Comentário enviado por ryonagana em 15/12/2008 - 18:21h

sim claro, é que eu confesso que nao sei usar malloc, calloc essas coisas
apesar de ser muito util, mas acho que esses comandos de C sao muito abaixo do nivel do c++
MAS se caso a pessoa quiser dar uma compatibilidade a mais, aconselho a usar esse modo
ou se a pessoa estiver programando um framework ,ou um sistema operacional e quiser fazer uma abstração de codigo


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts