É sempre aceitável ter um vazamento de memória no aplicativo C ou C ++?
E se você alocar alguma memória e usá-la até a última linha de código do seu aplicativo (por exemplo, o destruidor de um objeto global)? Contanto que o consumo de memória não cresça com o tempo, não há problema em confiar no sistema operacional para liberar sua memória quando o aplicativo terminar (no Windows, Mac e Linux)? Você consideraria isso um vazamento de memória real se a memória estivesse sendo usada continuamente até ser liberada pelo sistema operacional.
E se uma biblioteca de terceiros forçar essa situação com você? Recusaria usar essa biblioteca de terceiros, não importa quão grande ela possa ser?
Eu vejo apenas uma desvantagem prática, e é que esses vazamentos benignos aparecerão com as ferramentas de detecção de vazamento de memória como falsos positivos.
fonte
Respostas:
Não.
Como profissionais, a pergunta que não devemos nos perguntar é: "É certo fazer isso?" mas sim "Existe sempre um boa razão para fazer isso?" E "caçar esse vazamento de memória é uma dor" não é uma boa razão.
Eu gosto de manter as coisas simples. E a regra simples é que meu programa não tenha vazamentos de memória.
Isso também torna minha vida simples. Se eu detectar um vazamento de memória, eu o elimino, em vez de executar alguma estrutura elaborada da árvore de decisão para determinar se é um vazamento de memória "aceitável".
É semelhante aos avisos do compilador - o aviso será fatal para meu aplicativo em particular? Talvez não.
Mas, em última análise, é uma questão de disciplina profissional. Tolerar avisos do compilador e tolerar vazamentos de memória é um mau hábito que acabará me mordendo pela retaguarda.
Para levar as coisas ao extremo, seria aceitável para um cirurgião deixar algum equipamento operacional dentro de um paciente?
Embora seja possível que ocorra uma circunstância em que o custo / risco de remover essa peça de equipamento exceda o custo / risco de deixá-la dentro e que possa haver circunstâncias em que ela foi inofensiva, se eu vi essa pergunta postada no SurgeonOverflow.com e vi qualquer resposta diferente de "não", seria seriamente minar minha confiança na profissão médica.
-
Se uma biblioteca de terceiros me forçar a situação, isso levaria a suspeitar seriamente a qualidade geral da biblioteca em questão. Seria como se eu testasse dirigisse um carro e encontrasse duas arruelas e porcas soltas em um dos porta-copos - pode não ser um grande problema, mas retrata a falta de compromisso com a qualidade, por isso considero alternativas.
fonte
Não o considero um vazamento de memória, a menos que a quantidade de memória "usada" continue crescendo. Ter alguma memória não liberada, embora não seja ideal, não é um grande problema, a menos que a quantidade de memória necessária continue crescendo.
fonte
Vamos corrigir nossas definições primeiro. Uma memoria vazamento de ocorre quando a memória é alocada dinamicamente, por exemplo, com
malloc()
, e todas as referências à memória são perdidas sem a correspondente liberação livre. Uma maneira fácil de fazer um é assim:Observe que toda vez que o loop while (1), 1024 (+ overhead) bytes são alocados e o novo endereço é atribuído ao vp; não há ponteiro restante para os blocos comerciais anteriores. É garantido que este programa seja executado até que o heap se esgote, e não há como recuperar a memória do malloc'ed. A memória está "vazando" da pilha, para nunca mais ser vista.
O que você está descrevendo, no entanto, soa como
Você aloca a memória, trabalha com ela até o programa terminar. Isto é não um vazamento de memória; isso não prejudica o programa, e toda a memória será eliminada automaticamente quando o programa terminar.
Geralmente, você deve evitar vazamentos de memória. Primeiro, como a altitude acima de você e o combustível no hangar, a memória que vazou e não pode ser recuperada é inútil; segundo, é muito mais fácil codificar corretamente, sem vazar memória, no início do que encontrar um vazamento de memória posteriormente.
fonte
malloc
muita memória, é uma coisa ruim. Ainda não é um vazamento . Não é um vazamento até e a menos que seja umamalloc
memória para a qual a referência é perdida.Na teoria não, na prática depende .
Realmente depende da quantidade de dados que o programa está trabalhando, da frequência com que o programa é executado e se está ou não sendo executado constantemente.
Se eu tiver um programa rápido que leia uma pequena quantidade de dados faça um cálculo e saia, um pequeno vazamento de memória nunca será percebido. Como o programa não está sendo executado por muito tempo e usa apenas uma pequena quantidade de memória, o vazamento será pequeno e liberado quando o programa existir.
Por outro lado, se eu tiver um programa que processe milhões de registros e seja executado por um longo tempo, um pequeno vazamento de memória pode derrubar a máquina com tempo suficiente.
Quanto às bibliotecas de terceiros com vazamentos, se causarem um problema, corrija a biblioteca ou encontre uma alternativa melhor. Se não causar um problema, isso realmente importa?
fonte
Muitas pessoas parecem ter a impressão de que, uma vez liberada a memória, ela é instantaneamente retornada ao sistema operacional e pode ser usada por outros programas.
Isso não é verdade. Os sistemas operacionais geralmente gerenciam memória em páginas 4KiB.
malloc
e outros tipos de gerenciamento de memória obtêm páginas do sistema operacional e as sub-gerenciam como bem entenderem. É bastante provável quefree()
irá não retornar páginas para o sistema operacional, sob a suposição de que seu programa irá malloc mais memória mais tarde.Não estou dizendo que
free()
nunca devolve memória ao sistema operacional. Isso pode acontecer, principalmente se você estiver liberando grandes extensões de memória. Mas não há garantia.O fato importante: se você não liberar a memória da qual não precisa mais, garantimos que outros mallocs consumirão ainda mais memória. Mas se você liberar primeiro, o malloc poderá reutilizar a memória liberada.
O que isso significa na prática? Isso significa que, se você sabe que seu programa não exigirá mais memória a partir de agora (por exemplo, está na fase de limpeza), liberar memória não é tão importante. No entanto, se o programa puder alocar mais memória posteriormente, evite vazamentos de memória - principalmente aqueles que podem ocorrer repetidamente.
Consulte também este comentário para obter mais detalhes sobre por que liberar memória pouco antes da finalização é ruim.
Um comentarista não pareceu entender esse chamado
free()
não permite automaticamente que outros programas usem a memória liberada. Mas esse é o ponto inteiro desta resposta!Portanto, para convencer as pessoas, demonstrarei um exemplo em que free () faz muito pouco bem. Para facilitar a matemática, vou fingir que o sistema operacional gerencia memória em páginas de 4000 bytes.
Suponha que você aloque dez mil blocos de 100 bytes (por simplicidade, ignorarei a memória extra necessária para gerenciar essas alocações). Isso consome 1 MB ou 250 páginas. Se você liberar 9000 desses blocos aleatoriamente, ficará com apenas 1000 blocos - mas eles estão espalhados por todo o lugar. Estatisticamente, cerca de 5 páginas estarão vazias. Os outros 245 terão cada um pelo menos um bloco alocado. Isso equivale a 980 KB de memória, que não pode ser recuperado pelo sistema operacional - mesmo que agora você tenha apenas 100 KB alocados!
Por outro lado, agora você pode malloc () 9000 blocos a mais sem aumentar a quantidade de memória que seu programa está acumulando.
Mesmo quando tecnicamente
free()
poderia retornar memória ao sistema operacional, talvez não o fizesse. precisa alcançar um equilíbrio entre operar rapidamente e economizar memória. Além disso, um programa que já alocou muita memória e liberou, provavelmente o fará novamente. Um servidor da web precisa manipular solicitação após solicitação após solicitação - faz sentido manter alguma memória "folga" disponível para que você não precise solicitar memória ao sistema operacional o tempo todo.free()
fonte
Não há nada errado em termos de limpeza do sistema operacional após a execução do aplicativo.
Realmente depende do aplicativo e como ele será executado. É preciso cuidar de vazamentos que ocorrem continuamente em um aplicativo que precisa ser executado por semanas, mas uma pequena ferramenta que calcula um resultado sem uma necessidade de memória muito alta não deve ser um problema.
Há uma razão pela qual muitas linguagens de script não coletam lixo referências cíclicas ... para seus padrões de uso, não é um problema real e, portanto, seria tanto desperdício de recursos quanto a memória desperdiçada.
fonte
Acredito que a resposta é não, nunca permita vazamento de memória e tenho alguns motivos que não vi explicitamente declarados. Existem ótimas respostas técnicas aqui, mas acho que a resposta real depende de mais razões sociais / humanas.
(Primeiro, observe que, como outros mencionados, um verdadeiro vazamento ocorre quando o programa, a qualquer momento, perde o controle dos recursos de memória alocados. Em C, isso acontece quando você direciona
malloc()
um ponteiro e deixa esse ponteiro sair do escopo sem fazer uma açãofree()
primeiro.)O ponto crucial da sua decisão aqui é o hábito. Quando você codifica em um idioma que usa ponteiros, você usa muito os ponteiros . E ponteiros são perigosos; elas são a maneira mais fácil de adicionar todo tipo de problemas graves ao seu código.
Quando você está codificando, às vezes você fica com a bola e às vezes fica cansado, bravo ou preocupado. Durante esses tempos um pouco distraídos, você está codificando mais no piloto automático. O efeito do piloto automático não diferencia entre código único e um módulo em um projeto maior. Durante esses períodos, os hábitos que você estabelecer são o que acabará na sua base de código.
Portanto, nunca permita vazamentos de memória pela mesma razão que você ainda deve verificar seus pontos cegos ao mudar de faixa, mesmo se você for o único carro na estrada no momento. Durante os momentos em que seu cérebro ativo está distraído, bons hábitos são tudo o que pode salvá-lo de erros desastrosos.
Além da questão do "hábito", os indicadores são complexos e geralmente exigem muito poder do cérebro para rastrear mentalmente. É melhor não "enlamear a água" quando se trata de usar ponteiros, especialmente quando você é iniciante em programação.
Há um aspecto mais social também. Com o uso adequado de
malloc()
efree()
, qualquer pessoa que consulte seu código ficará à vontade; você está gerenciando seus recursos. Caso contrário, eles suspeitarão imediatamente de um problema.Talvez você tenha percebido que o vazamento de memória não prejudica nada nesse contexto, mas todo mantenedor do seu código também terá que resolver isso na cabeça dele quando ler esse trecho de código. Ao usar,
free()
você remove a necessidade de considerar o problema.Finalmente, a programação está escrevendo um modelo mental de processo em uma linguagem inequívoca, para que uma pessoa e um computador possam entender perfeitamente o processo. Uma parte vital das boas práticas de programação nunca é introduzir ambiguidade desnecessária.
A programação inteligente é flexível e genérica. Uma programação ruim é ambígua.
fonte
new
, o que elimina a maioria dos vazamentos de memória imediatamente. Somente se você absolutamente precisar usá-lonew
. O resultado dissonew
deve ser imediatamente colocado em um ponteiro inteligente. Se você seguir essas duas regras, simplesmente nunca vazará memória (exceto um bug em uma biblioteca). O único caso restante são osshared_ptr
ciclos, caso em que você precisa saber para usarweak_ptr
.Acho que na sua situação a resposta pode ser que está tudo bem. Mas você definitivamente precisa documentar que o vazamento de memória é uma decisão consciente. Você não quer que um programador de manutenção apareça, coloque seu código em uma função e chame um milhão de vezes. Portanto, se você decidir que um vazamento está correto, é necessário documentá-lo (EM GRANDES LETRAS) para quem precisar trabalhar no programa no futuro.
Se essa é uma biblioteca de terceiros, você pode ficar preso. Mas definitivamente documente que esse vazamento ocorre.
Mas, basicamente, se o vazamento de memória é uma quantidade conhecida, como um buffer de 512 KB ou algo assim, não é um problema. Se o vazamento de memória continuar crescendo, como sempre que você chama uma biblioteca, sua memória aumenta em 512 KB e não é liberada, então você pode ter um problema. Se você o documentar e controlar o número de vezes que a chamada é executada, poderá ser gerenciável. Mas você realmente precisa de documentação porque, embora 512 não seja muito, 512 mais de um milhão de chamadas são muitas.
Além disso, você precisa verificar a documentação do sistema operacional. Se este era um dispositivo incorporado, pode haver sistemas operacionais que não liberam toda a memória de um programa que sai. Não tenho certeza, talvez isso não seja verdade. Mas vale a pena investigar.
fonte
Vou dar a resposta impopular, mas prática, de que é sempre errado liberar memória, a menos que isso reduza o uso de memória do seu programa . Por exemplo, um programa que faz uma única alocação ou uma série de alocações para carregar o conjunto de dados que ele usará durante toda a sua vida útil não precisa liberar nada. No caso mais comum de um programa grande com requisitos de memória muito dinâmicos (pense em um navegador da web), você obviamente deve liberar memória que não está mais usando o mais rápido possível (por exemplo, fechando uma guia / documento / etc.) , mas não há motivo para liberar nada quando o usuário seleciona cliques em "sair", e isso é realmente prejudicial à experiência do usuário.
Por quê? Liberar memória requer tocar na memória. Mesmo que a implementação do malloc do sistema não armazene metadados adjacentes aos blocos de memória alocados, você provavelmente estará andando por estruturas recursivas apenas para encontrar todos os indicadores necessários para liberar.
Agora, suponha que seu programa tenha trabalhado com um grande volume de dados, mas não tenha tocado na maioria deles por um tempo (novamente, o navegador da web é um ótimo exemplo). Se o usuário estiver executando muitos aplicativos, uma boa parte desses dados provavelmente foi trocada para o disco. Se você simplesmente sair (0) ou retornar do main, ele sai instantaneamente. Ótima experiência do usuário. Se você se esforçar para tentar liberar tudo, poderá gastar 5 segundos ou mais trocando todos os dados novamente, apenas para jogá-los fora imediatamente depois disso. Perda de tempo do usuário. Desperdício da vida da bateria do laptop. Desperdício de desgaste no disco rígido.
Isso não é apenas teórico. Sempre que me vejo com muitos aplicativos carregados e o disco começa a ser debulhado, nem considero clicar em "sair". Chego a um terminal o mais rápido possível e digito killall -9 ... porque sei que "exit" apenas piorará.
fonte
Tenho certeza de que alguém pode apresentar um motivo para dizer Sim, mas não sou eu. Em vez de dizer não, vou dizer que isso não deve ser uma pergunta de sim / não. Existem maneiras de gerenciar ou conter vazamentos de memória, e muitos sistemas os possuem.
Existem sistemas da NASA em dispositivos que deixam a Terra planejando isso. Os sistemas serão reiniciados automaticamente de vez em quando, para que vazamentos de memória não sejam fatais para a operação geral. Apenas um exemplo de contenção.
fonte
Se você alocar memória e usá-la até a última linha do seu programa, isso não será um vazamento. Se você alocar memória e esquecê-la, mesmo que a quantidade de memória não esteja aumentando, isso é um problema. Essa memória alocada, mas não utilizada, pode fazer com que outros programas fiquem mais lentos ou nem um pouco.
fonte
Posso contar por um lado o número de vazamentos "benignos" que vi ao longo do tempo.
Portanto, a resposta é um sim muito qualificado.
Um exemplo. Se você possui um recurso singleton que precisa de um buffer para armazenar uma fila ou deque circular, mas não sabe qual o tamanho do buffer e não pode suportar a sobrecarga do bloqueio ou de cada leitor, aloque um buffer que exponha a duplicação, mas não liberar os antigos vazará uma quantidade limitada de memória por fila / deque. A vantagem disso é que eles aceleram drasticamente todos os acessos e podem alterar os assintóticos das soluções de multiprocessadores, sem arriscar a disputa por um bloqueio.
Vi essa abordagem ser muito benéfica para coisas com contagens muito claramente definidas, como deques de roubo de trabalho por CPU e em um grau muito menor no buffer usado para armazenar o singleton
/proc/self/maps
estado no coletor de lixo conservador de Hans Boehm para C / C ++, que é usado para detectar os conjuntos raiz, etc.Embora tecnicamente um vazamento, ambos os casos sejam limitados em tamanho e no trabalho circular expansível que rouba o caso deque, há uma enorme vitória de desempenho em troca de um fator limitado de 2 aumento no uso de memória para as filas.
fonte
Se você alocar um monte de heap no início do seu programa, e não o liberar ao sair, isso não é um vazamento de memória em si. Um vazamento de memória ocorre quando o programa faz um loop em uma seção do código, e esse código aloca o heap e, em seguida, "perde o controle" dele sem liberá-lo.
De fato, não há necessidade de fazer chamadas para liberar () ou excluir antes de sair. Quando o processo termina, toda a sua memória é recuperada pelo sistema operacional (esse é certamente o caso do POSIX. Em outros sistemas operacionais - particularmente os incorporados - YMMV).
O único cuidado que eu teria ao não liberar a memória no momento da saída é que, se você refatorar seu programa para que, por exemplo, se torne um serviço que aguarda entrada, faça o que seu programa fizer, faça um loop para aguardar outra chamada de serviço, o que você codificou pode se transformar em um vazamento de memória.
fonte
isso é tão específico do domínio que dificilmente vale a pena responder. use sua cabeça em pânico.
e existe um espectro de situações intermediárias.
o custo de oportunidade ($$$) de adiar a liberação de um produto para corrigir todos os problemas, exceto os piores vazamentos de memória, geralmente diminui a sensação de ser "desleixado ou não profissional". Seu chefe paga para você ganhar dinheiro, não para ter sentimentos quentes e confusos.
fonte
Você deve primeiro perceber que há uma grande diferença entre um vazamento de memória percebido e um vazamento de memória real. Com muita frequência, as ferramentas de análise relatam muitos erros e rotulam algo como vazado (memória ou recursos como alças, etc.) onde realmente não está. Muitas vezes, isso ocorre devido à arquitetura da ferramenta de análise. Por exemplo, certas ferramentas de análise relatam objetos de tempo de execução como vazamentos de memória porque nunca os veem liberados. Mas a desalocação ocorre no código de desligamento do tempo de execução, que a ferramenta de análise pode não conseguir ver.
Com isso dito, ainda haverá momentos em que você terá vazamentos reais de memória que são muito difíceis de encontrar ou muito difíceis de corrigir. Então agora a questão é: está tudo bem em deixá-los no código?
A resposta ideal é "não, nunca". Uma resposta mais pragmática pode ser "não, quase nunca". Muitas vezes, na vida real, você tem um número limitado de recursos e tempo para resolver e uma lista interminável de tarefas. Quando uma das tarefas é eliminar vazamentos de memória, muitas vezes entra em vigor a lei dos retornos decrescentes. Você pode eliminar, digamos, 98% de todos os vazamentos de memória em um aplicativo em uma semana, mas os 2% restantes podem levar meses. Em alguns casos, pode até ser impossível eliminar certos vazamentos devido à arquitetura do aplicativo sem uma grande refatoração de código. Você precisa pesar os custos e os benefícios de eliminar os 2% restantes.
fonte
Nesse tipo de questão, o contexto é tudo. Pessoalmente, não suporto vazamentos e, no meu código, faço um grande esforço para corrigi-los se eles surgirem, mas nem sempre vale a pena consertar um vazamento, e quando as pessoas estão me pagando pela hora que tenho ocasionalmente disse-lhes que não valia a pena pagar uma correção no código deles. Deixe-me lhe dar um exemplo:
Eu estava supervisionando um projeto, realizando alguns trabalhos de aperfeiçoamento e corrigindo muitos bugs. Houve um vazamento durante a inicialização dos aplicativos que eu rastreei e compreendi completamente. Para corrigi-lo corretamente, seria necessário um dia ou mais para refatorar um pedaço de código funcional. Eu poderia ter feito algo hacky (como colocar o valor em um global e capturá-lo em algum momento, sei que não estava mais em uso para liberar), mas isso teria causado mais confusão ao próximo cara que precisou tocar no código.
Pessoalmente, eu não teria escrito o código dessa maneira em primeiro lugar, mas a maioria de nós nem sempre trabalha em bases de código bem desenhadas e bem desenhadas, e às vezes você precisa observar essas coisas de forma pragmática. A quantidade de tempo que levaria para corrigir esse vazamento de 150 bytes poderia ser gasto em aprimoramentos algorítmicos que eliminavam megabytes de memória RAM.
Por fim, decidi que não valia a pena consertar o vazamento de 150 bytes para um aplicativo usado em torno de um gig de memória ram e executado em uma máquina dedicada, por isso escrevi um comentário dizendo que havia vazamento, o que precisava ser alterado para corrigir e por que não valia a pena na época.
fonte
Embora a maioria das respostas se concentre em vazamentos de memória real (que nunca são bons, porque são um sinal de codificação superficial), essa parte da pergunta parece mais interessante para mim:
Se a memória associada for usada, você não poderá liberá-la antes que o programa termine. Se a liberação é feita pela saída do programa ou pelo sistema operacional, não importa. Enquanto isso estiver documentado, para que as alterações não apresentem vazamentos reais de memória e contanto que não haja destruidor de C ++ ou função de limpeza de C envolvida na imagem. Um arquivo não fechado pode ser revelado através de um
FILE
objeto vazado , mas uma falta de fclose () também pode fazer com que o buffer não seja liberado.Portanto, voltando ao caso original, o IMHO é perfeitamente bom em si, tanto que o Valgrind, um dos detectores de vazamento mais poderosos, tratará esses vazamentos apenas se solicitado. No Valgrind, quando você sobrescreve um ponteiro sem liberá-lo antes, ele é considerado um vazamento de memória, porque é mais provável que ocorra novamente e faça com que o heap cresça infinitamente.
Então, não há blocos de memória nfreed que ainda possam ser acessados. Pode-se garantir a libertação de todos eles na saída, mas isso é apenas uma perda de tempo. A questão é se eles poderiam ser libertados antes . Diminuir o consumo de memória é útil em qualquer caso.
fonte
Eu concordo com o vfilby - depende. No Windows, tratamos os vazamentos de memória como erros relativamente graves. Mas, depende muito do componente.
Por exemplo, vazamentos de memória não são muito graves para componentes que são executados raramente e por períodos limitados. Esses componentes são executados, executam o trabalho e depois saem. Quando eles saem, toda a sua memória é liberada implicitamente.
No entanto, vazamentos de memória em serviços ou outros componentes de longo prazo (como o shell) são muito graves. A razão é que esses erros "roubam" a memória ao longo do tempo. A única maneira de recuperar isso é reiniciar os componentes. A maioria das pessoas não sabe como reiniciar um serviço ou o shell - por isso, se o desempenho do sistema sofrer, eles simplesmente reiniciarão.
Então, se você tiver um vazamento - avalie seu impacto de duas maneiras
Foredecker
fonte
Mesmo se você tiver certeza de que seu vazamento de memória 'conhecido' não causará estragos, não faça isso. Na melhor das hipóteses, isso abrirá um caminho para você cometer um erro semelhante e provavelmente mais crítico em um horário e local diferentes.
Para mim, perguntar isso é como questionar "Posso quebrar o sinal vermelho às 3 da manhã quando ninguém está por perto?". Certamente, pode não causar nenhum problema naquele momento, mas fornecerá uma alavanca para você fazer o mesmo na hora do rush!
fonte
Não, você não deve ter vazamentos que o sistema operacional irá limpar para você. O motivo (não mencionado nas respostas acima, tanto quanto pude verificar) é que você nunca sabe quando seu main () será reutilizado como função / módulo em outro programa . Se o seu main () passa a ser uma função freqüentemente chamada no software de outras pessoas - esse software terá um vazamento de memória que consome memória ao longo do tempo.
KIV
fonte
Eu acho que tudo bem se você estiver escrevendo um programa destinado a vazar memória (isto é, para testar o impacto de vazamentos de memória no desempenho do sistema).
fonte
Estou surpreso ao ver tantas definições incorretas do que realmente é um vazamento de memória. Sem uma definição concreta, uma discussão sobre se é algo ruim ou não não vai a lugar algum.
Como alguns comentaristas apontaram corretamente, um vazamento de memória ocorre apenas quando a memória alocada por um processo sai do escopo na medida em que o processo não é mais capaz de fazer referência ou excluí-lo.
Um processo que capta cada vez mais memória não está necessariamente vazando. Desde que seja capaz de referenciar e desalocar essa memória, ela permanece sob o controle explícito do processo e não vazou. O processo pode muito bem ser mal projetado, especialmente no contexto de um sistema em que a memória é limitada, mas isso não é o mesmo que um vazamento. Por outro lado, perder o escopo de, digamos, um buffer de 32 bytes ainda é um vazamento, mesmo que a quantidade de memória vazada seja pequena. Se você acha que isso é insignificante, aguarde até que alguém envolva um algoritmo na chamada da sua biblioteca e o chame 10.000 vezes.
Não vejo nenhuma razão para permitir vazamentos em seu próprio código, por menor que seja. As linguagens de programação modernas, como C e C ++, se esforçam muito para ajudar os programadores a evitar tais vazamentos e raramente há um bom argumento para não adotar boas técnicas de programação - especialmente quando combinadas com recursos específicos de linguagem - para evitar vazamentos.
No que diz respeito ao código existente ou de terceiros, em que seu controle sobre a qualidade ou a capacidade de fazer uma alteração pode ser altamente limitado, dependendo da gravidade do vazamento, você pode ser forçado a aceitar ou tomar medidas mitigadoras, como reiniciar seu processo regularmente para reduzir o efeito do vazamento.
Pode não ser possível alterar ou substituir o código existente (vazando) e, portanto, você pode aceitá-lo. No entanto, isso não é o mesmo que declarar que está OK.
fonte
Realmente não é um vazamento, se é intencional e não é um problema, a menos que seja uma quantidade significativa de memória ou pode crescer para ser uma quantidade significativa de memória. É bastante comum não limpar alocações globais durante a vida útil de um programa. Se o vazamento ocorrer em um servidor ou aplicativo de longa duração, crescer com o tempo, isso é um problema.
fonte
Eu acho que você respondeu sua própria pergunta. A maior desvantagem é como elas interferem nas ferramentas de detecção de vazamento de memória, mas acho que essa desvantagem é enorme para certos tipos de aplicativos.
Eu trabalho com aplicativos de servidor legados que deveriam ser sólidos, mas eles têm vazamentos e os globais atrapalham as ferramentas de detecção de memória. É um grande negócio.
No livro "Collapse", de Jared Diamond, o autor se pergunta sobre o que o cara estava pensando que cortou a última árvore na Ilha de Páscoa, a árvore que ele precisaria para construir uma canoa para sair da ilha. Eu me pergunto sobre o dia de muitos anos atrás em que a primeira global foi adicionada à nossa base de código. Esse foi o dia em que deveria ter sido pego.
fonte
Vejo o mesmo problema em todas as perguntas do cenário como esta: O que acontece quando o programa muda e, de repente, esse pequeno vazamento de memória é chamado dez milhões de vezes e o final do programa está em um local diferente, então isso importa? Se estiver em uma biblioteca, registre um bug com os mantenedores da biblioteca, não coloque um vazamento em seu próprio código.
fonte
Eu vou responder não.
Em teoria, o sistema operacional será limpo após você se você deixar uma bagunça (agora isso é rude, mas como os computadores não têm sentimentos, pode ser aceitável). Mas você não pode prever todas as situações possíveis que possam ocorrer quando o programa for executado. Portanto (a menos que você consiga realizar uma prova formal de algum comportamento), criar vazamentos de memória é irresponsável e desleixado do ponto de vista profissional.
Se um componente de terceiros vazar memória, esse é um argumento muito forte contra seu uso, não apenas por causa do efeito iminente, mas também porque mostra que os programadores trabalham de maneira desleixada e que isso também pode afetar outras métricas. Agora, ao considerar sistemas legados, isso é difícil (considere os componentes de navegação na Web: que eu saiba, todos eles vazam memória), mas deve ser a norma.
fonte
Historicamente, isso importava em alguns sistemas operacionais em alguns casos extremos. Esses casos extremos podem existir no futuro.
Aqui está um exemplo: no SunOS na era Sun 3, havia um problema: se um processo usasse exec (ou mais tradicionalmente fork e, em seguida, exec), o novo processo subsequente herdaria o mesmo espaço de memória que o pai e não poderia ser reduzido . Se um processo pai alocasse 1/2 gig de memória e não a liberasse antes de chamar o exec, o processo filho começaria a usar esse mesmo 1/2 gig (mesmo que não tenha sido alocado). Esse comportamento foi melhor exibido pelo SunTools (seu sistema de janelas padrão), que era um porco da memória. Todos os aplicativos gerados foram criados via fork / exec e herdaram a pegada do SunTools, preenchendo rapidamente o espaço de troca.
fonte
Isso já foi discutido ad nauseam . Resumindo, um vazamento de memória é um bug e deve ser corrigido. Se uma biblioteca de terceiros vaza memória, ele se pergunta o que mais há de errado com ela, não? Se você estivesse construindo um carro, usaria um motor que ocasionalmente vaza óleo? Afinal, alguém fez o motor, então não é sua culpa e você não pode consertá-lo, certo?
fonte
Geralmente, um vazamento de memória em um aplicativo independente não é fatal, pois é limpo quando o programa é encerrado.
O que você faz com os programas de servidor projetados para que não saiam?
Se você é o tipo de programador que não cria e implementa código em que os recursos são alocados e liberados corretamente, não quero nada com você ou seu código. Se você não se importa de limpar sua memória vazada, e as fechaduras? Você os deixa lá fora também? Você deixa pequenos pedaços de arquivos temporários espalhados em vários diretórios?
Vazou essa memória e deixou o programa limpá-la? Não. Absolutamente não. É um mau hábito, que leva a bugs, bugs e mais bugs.
Limpe depois de si mesmo. Sua mãe não trabalha mais aqui.
fonte
Como regra geral, se você tem vazamentos de memória que considera que não pode evitar, precisa pensar mais sobre a propriedade do objeto.
Mas, para sua pergunta, minha resposta, em poucas palavras, é No código de produção, sim. Durante o desenvolvimento, não . Isso pode parecer inverso, mas eis o meu raciocínio:
Na situação que você descreve, onde a memória é mantida até o final do programa, não há problema em não liberá-la. Quando o processo terminar, o sistema operacional será limpo de qualquer maneira. De fato, isso pode melhorar a experiência do usuário: em um jogo em que trabalhei, os programadores pensaram que seria mais fácil liberar toda a memória antes de sair, fazendo com que o desligamento do programa levasse meio minuto! Uma mudança rápida que acabou de chamar exit () fez o processo desaparecer imediatamente e colocou o usuário de volta na área de trabalho onde ele queria estar.
No entanto, você está certo sobre as ferramentas de depuração: elas funcionam bem, e todos os falsos positivos podem fazer com que encontrar sua memória real vaze uma dor. E, por isso, sempre escreva o código de depuração que libera a memória e desative-o quando você enviar.
fonte