Já tive vazamentos de memória muitas vezes. Normalmente, quando estou malloc
pensando que não há amanhã, ou pendurada FILE *
como roupa suja. Eu geralmente suponho (leia: espero desesperadamente) que toda a memória é limpa pelo menos quando o programa termina. Existem situações em que a memória perdida não será coletada quando o programa for encerrado ou travado?
Se a resposta varia muito de uma linguagem para outra, vamos nos concentrar em C (++).
Observe o uso hiperbólico da frase 'como se não houvesse amanhã' e 'pendurado ... como roupa suja'. Inseguro * malloc
* ing pode prejudicar quem você ama. Além disso, tenha cuidado com a roupa suja.
c++
c
memory
memory-leaks
DilithiumMatrix
fonte
fonte
calloc
gostaria que não houvesse amanhã. Excelente.Respostas:
Não. Os sistemas operacionais liberam todos os recursos mantidos pelos processos quando eles saem.
Isso se aplica a todos os recursos que o sistema operacional mantém: memória, arquivos abertos, conexões de rede, identificadores de janela ...
Dito isso, se o programa estiver sendo executado em um sistema embarcado sem sistema operacional ou com um sistema operacional muito simples ou cheio de erros, a memória pode ficar inutilizável até a reinicialização. Mas se você estivesse nessa situação, provavelmente não estaria fazendo esta pergunta.
O sistema operacional pode levar muito tempo para liberar certos recursos. Por exemplo, a porta TCP que um servidor de rede usa para aceitar conexões pode levar alguns minutos para ficar livre, mesmo se fechada corretamente pelo programa. Um programa em rede também pode conter recursos remotos , como objetos de banco de dados. O sistema remoto deve liberar esses recursos quando a conexão de rede for perdida, mas pode demorar ainda mais do que o sistema operacional local.
fonte
ipcrm
limpeza manual, linux.die.net/man/8/ipcrm .O padrão C não especifica que a memória alocada por
malloc
seja liberada quando o programa termina. Isso feito pelo sistema operacional e nem todos os sistemas operacionais (geralmente estes estão no mundo integrado) liberam a memória quando o programa termina.fonte
main
retorna toda a memória alocada pelomalloc
é liberada. Por exemplo, ele diz que todos os arquivos abertos são fechados antes do encerramento do programa. Para memória alocadamalloc
, simplesmente não é especificado. É claro que minha frase sobre o sistema operacional descreve o que normalmente é feito, não o que o padrão prescreve, pois não especifica nada sobre isso.std::atexit
também considera o encerramento do programa por meio destd::exit
, e há tambémstd::abort
e (específico do C ++)std::terminate
.atexit
não seria utilizável. :-)Como todas as respostas cobriram a maioria dos aspectos de sua pergunta sobre sistemas operacionais modernos, mas historicamente, há um que vale a pena mencionar se você já programou no mundo DOS. Os programas Terminant and Stay Resident (TSR) normalmente devolveriam o controle ao sistema, mas residiriam na memória que poderia ser revivida por uma interrupção de software / hardware. Era normal ver mensagens como "sem memória! Tente descarregar alguns de seus TSRs" ao trabalhar nesses sistemas operacionais.
Então, tecnicamente, o programa termina , mas como ele ainda reside na memória, qualquer vazamento de memória não seria liberado a menos que você descarregue o programa.
Portanto, você pode considerar que este é outro caso além dos sistemas operacionais que não estão reivindicando memória, seja porque há bugs ou porque o sistema operacional integrado foi projetado para isso.
Lembro-me de mais um exemplo. O Customer Information Control System (CICS), um servidor de transações que é executado principalmente em mainframes IBM, é pseudo-conversacional. Quando executado, ele processa os dados inseridos pelo usuário, gera outro conjunto de dados para o usuário, transfere para o nó terminal do usuário e finaliza. Ao ativar a chave de atenção, ela se reativa novamente para processar outro conjunto de dados. Devido à maneira como ele se comporta, tecnicamente novamente, o SO não recuperará memória dos Programas CICS encerrados, a menos que você recicle o servidor de transações CICS.
fonte
Como os outros já disseram, a maioria dos sistemas operacionais irá recuperar a memória alocada após o término do processo (e provavelmente outros recursos como soquetes de rede, identificadores de arquivo, etc).
Dito isso, a memória pode não ser a única coisa com a qual você precisa se preocupar ao lidar com new / delete (ao invés de raw malloc / free). A memória alocada em novo pode ser recuperada, mas as coisas que podem ser feitas nos destruidores dos objetos não acontecerão. Talvez o destruidor de alguma classe grave um valor sentinela em um arquivo após a destruição. Se o processo simplesmente terminar, o identificador de arquivo pode ser liberado e a memória recuperada, mas esse valor sentinela não seria gravado.
Moral da história, sempre limpe depois de você mesmo. Não deixe as coisas balançarem. Não confie na limpeza do sistema operacional depois de você. Limpe depois de você mesmo.
fonte
kill -9
ventilador menos que brilhante apareça ...)std::exit
chamará dtors,std::abort
não, talvez exceções não detectadas.É mais provável que isso dependa do sistema operacional do que do idioma. Em última análise, qualquer programa em qualquer idioma obterá sua memória do sistema operacional.
Nunca ouvi falar de um sistema operacional que não recicla a memória quando um programa é encerrado / travado. Portanto, se o seu programa tem um limite superior na memória que precisa alocar, então apenas alocar e nunca liberar é perfeitamente razoável.
fonte
Se o programa for transformado em um componente dinâmico ("plugin") que é carregado no espaço de endereço de outro programa, será problemático, mesmo em um sistema operacional com gerenciamento de memória organizado. Não precisamos nem pensar no código sendo portado para sistemas menos capazes.
Por outro lado, a liberação de toda a memória pode afetar o desempenho da limpeza de um programa.
Em um programa em que eu estava trabalhando, um determinado caso de teste exigia 30 segundos ou mais para o programa sair, porque estava recorrendo ao gráfico de toda a memória dinâmica e liberando-o peça por peça.
Uma solução razoável é ter o recurso lá e cobri-lo com casos de teste, mas desligá-lo no código de produção para que o aplicativo feche rapidamente.
fonte
Todos os sistemas operacionais que merecem o título irão limpar a bagunça que seu processo fez após o término. Mas sempre há imprevistos, e se fosse negado o acesso de alguma forma e algum pobre programador não previsse a possibilidade e então não tente novamente um pouco mais tarde? É sempre mais seguro apenas se limpar SE os vazamentos de memória forem essenciais - caso contrário, não vale o esforço IMO se esse esforço for caro.
Edit: Você precisa limpar vazamentos de memória se eles estiverem no lugar onde eles se acumulam, como em loops. Os vazamentos de memória de que falo são aqueles que se acumulam em tempo constante durante o curso do programa; se você tiver um vazamento de qualquer outro tipo, provavelmente será um problema sério mais cedo ou mais tarde.
Em termos técnicos, se seus vazamentos são de 'complexidade' de memória O (1), eles são bons na maioria dos casos, O (logn) já desagradável (e em alguns casos fatais) e O (N) + intolerável.
fonte
A memória compartilhada em sistemas compatíveis com POSIX persiste até que shm_unlink seja chamado ou o sistema seja reinicializado.
fonte
Se você tiver comunicação entre processos, isso pode fazer com que outros processos nunca concluam e consumam recursos, dependendo do protocolo.
Para dar um exemplo, uma vez eu estava experimentando imprimir em uma impressora PDF em Java quando encerrei o JVM no meio de um trabalho de impressora, o processo de spool de PDF permaneceu ativo e tive que encerrá-lo no gerenciador de tarefas antes de poder tente imprimir novamente.
fonte