Abordagens para Gerenciamento de Memória
Tradicionalmente, as linguagens se dividem em duas grandes categorias:
- Controle total através do gerenciamento manual de memória: C, C++, Pascal, ...
- Programador decide quando alocar ou liberar memória do heap.
- Programador deve determinar se um ponteiro ainda aponta para uma memória válida.
- Estudos mostram que os programadores cometem erros.
- Segurança total através do gerenciamento automático de memória em tempo de execução: Java, Python, Go, Haskell, ...
- Um sistema em tempo de execução garante que a memória não seja liberada até que não possa mais ser referenciada.
- Normalmente implementado com contagem de referência, coleta de lixo ou RAII.
Rust oferece uma nova combinação:
Controle total e segurança por imposição do correto gerenciamento de memória em tempo de compilação.
Ele faz isso com um conceito de ownership (posse) explícito.
Este slide tem a intenção de ajudar os alunos que vêm de outras linguagens a colocar o Rust em contexto.
-
Em C, o gerenciamento do heap é feito manualmente com
malloc
efree
. Os erros comuns incluem esquecer de chamarfree
, chamá-lo várias vezes para o mesmo ponteiro ou desreferenciar um ponteiro depois que a memória para a qual ele aponta foi liberada. -
O C++ possui ferramentas como ponteiros inteligentes (
unique_ptr
,shared_ptr
) que aproveitam as garantias da linguagem sobre a chamada de destrutores para garantir que a memória seja liberada quando uma função retorna. Ainda é muito fácil usar essas ferramentas de maneira incorreta e criar bugs semelhantes aos do C. -
Java, Go e Python dependem do coletor de lixo para identificar a memória que não é mais acessível e descartá-la. Isso garante que qualquer ponteiro possa ser desreferenciado, eliminando o uso após a liberação e outras classes de bugs. Mas, o coletor de lixo tem um custo de tempo de execução e é difícil de ajustar corretamente.
O modelo de ownership e borrowing do Rust pode, em muitos casos, obter o desempenho do C, com operações de alocação e liberação precisamente onde elas são necessárias - custo zero. Ele também fornece ferramentas semelhantes aos ponteiros inteligentes do C++. Quando necessário, outras opções, como contagem de referência, estão disponíveis, e até mesmo crates de terceiros estão disponíveis para suportar a coleta de lixo em tempo de execução (não abordada nesta aula).