Vazamento de memória

Fenômeno computacional

Em ciência da computação vazamento de memória ou memory leak é um fenômeno que ocorre quando um programa de computador gerencia incorretamente alocações de memória de maneira que certa memória não é liberada quando não é mais necessária. Um vazamento de memória também pode acontecer quando um objeto é armazenado na memória mas não pode mais ser acessado pelo código em execução.[1] Um vazamento de memória tem sintomas similares a diversos outros problemas, portanto o diagnóstico usualmente requer que o desenvolvedor tenha acesso ao código-fonte do programa.

A ocorrência de vazamentos de memória é quase sempre relacionada a erros de programação e pode levar a falhas no sistema se a memória for completamente consumida.

Como os vazamentos de memória podem exaurir a memória do sistema conforme a aplicação roda, eles são um frequente fator contribuinte para o envelhecimento de software.

Efeitos

editar

Se um programa tem vazamento de memória e seu uso aumenta de maneira estável, geralmente não haverá um sintoma imediato. Como todo sistema físico tem uma quantia finita de memória, e se o vazamento de memória não for contido (por exemplo, ao reiniciar o programa), isso irá eventualmente causar problemas.

Quando toda a memória de um sistema for exaurida (seja ela memória virtual ou apenas memória principal, como num sistema embarcado), qualquer tentativa de alocação de memória irá falhar. Isso usualmente faz o programa que tenta alocar memória terminar ou gerar uma falha de segmentação. Alguns programas são projetados para se recuperar dessa situação (possivelmente por usar memória pré-reservada como fallback).

Alguns sistemas operacionais multitarefa tem mecanismos especiais para lidar com falta de memória, como matar processos aleatoriamente (o que pode afetar processos "inocentes"), ou matar o maior processo na memória (que presumivelmente está causando o problema). Alguns sistemas operacionais tem um limite de memória por processo, para impedir qualquer

Se o vazamento de memória for no kernel, o sistema operacional provavelmente irá falhar. Computadores sem gerenciamento de memória sofisticado, como sistemas embarcados, poderá falhar completamente com um vazamento persistente de memória.

Sistemas publicamente acessíveis, como servidores web ou roteadores são suscetíveis a ataques de negação de serviço se um invasor descobrir uma sequência de operações que pode ativar um vazamento. Tal sequência é um exemplo de exploit.

 
O padrão "dente de serra" de utilização de memória: a queda repentina no uso de memória é uma candidata a sintoma de vazamento de memória.

Um padrão de utilização de memória "sawtooth" pode ser um indicador de um vazamento de memória dentro de uma aplicação, particularmente se uma queda vertical coincide com reinicialização do sistema ou reinicio da aplicação. Deve haver cuidado, no entanto, porque o ponto de coleta de lixo do garbage collector também podem causar tal padrão e mostraria um uso saudável da pilha.

Exemplo

editar

O exemplo abaixo, escrito na linguagem de programação C, mostra um programa de computador que possui um vazamento de memória. Após algum tempo de execução este programa irá consumir toda a memória disponível e irá falhar.

#include <stdio.h>
#include <stdlib.h>

void f(void){
    void* s;
    s = malloc(50); /* obtém a memória */
    return;  /* memory leak - ver nota abaixo */ 

    /* 
     * A [[Memória (computador)|memória]] é obtida e disponibilizada em s.
     * Após o retorno da [[subrotina|função]], o [[Ponteiro (programação)|ponteiro]] é destruído e
     * perde-se a referência a esta porção de memória.
     * 
     * Este código pode ser consertado se a função f() incluir
     * a operação "free(s)" antes do retorno ou se o código
     * que chama f() fizer a chamada para a operação free().
     */
}

int main(void){
    /* Este ''loop'' infinito chama a função f(), definida acima */
    while (1) f(); /* Cedo ou tarde a chamada à função irá falhar, devido a um
                      erro de alocação na função malloc, quando a memória terminar.*/
    return 0;
}

Outro exemplo de vazamento de memória, só que agora utilizando a linguagem de programação C++, dependendo do computador e da quantidade de memória, o programa usará 100% da memória em milésimos

int main()
{
    while(true)
    {
        int * vetor = new int[100000]; // Em cada loop será consumido 400000 bytes(100000 * sizeof(int)) de memória ram.
        
        /* ... */
        
        // Para resolver o problema basta colocar um "delete vetor;" no final do loop.
    }
    return 0;
}

Referências

  1. «Creating a memory leak with Java». Stack Overflow. Consultado em 30 de março de 2019