O Go está sujeito aos mesmos vazamentos sutis de memória que o Java está?

91

Aqui estão os fatos:

  • a linguagem Go tem um coletor de lixo.

  • Java tem uma coleta de lixo

  • muitos programas Java têm (sutis ou não) vazamentos de memória

Como exemplo de um programa Java que tem vazamentos de memória (não para os fracos de coração, a questão pode abalar suas crenças), veja aqui um pequeno programa Java chamado Tomcat que tem até um botão "encontrar vazamentos": Existe uma maneira evitar vazamentos de memória de desdobramento no Tomcat?

Portanto, estou me perguntando: os programas escritos em Go exibirão o mesmo tipo de vazamento de memória (sutil ou não) que alguns programas escritos em Java exibem?

SintaxeT3rr0r
fonte
29
"muitos programas Java têm (sutis ou não) vazamentos de memória", você tem alguma evidência desse "fato" ou é apenas um ponto de discussão.
Peter Lawrey
17
@Webinator: Acho que você precisa dar um exemplo de um desses "vazamentos sutis de memória" que "muitos" programas Java têm. A menos que você esteja reivindicando um bug no coletor de lixo, a única maneira de vazar memória em Java puro é manter referências que você não está mais usando, por exemplo, colocando objetos em uma coleção e nunca removendo-os dessa coleção. Se este é o tipo de vazamento a que você está se referindo, nenhum idioma no mundo irá proteger contra eles, incluindo Go.
JeremyP
14
Aqui estão os vazamentos de memória sobre os quais eu estava falando (+200 votos positivos, respostas com +150 votos positivos, muitos vazamentos reais de memória Java explicados): stackoverflow.com/questions/6470651/…
SyntaxT3rr0r
6
É claro que os programas JAVA têm vazamentos de memória, apenas esqueça de definir alguma referência como null quando você não precisar mais deles. Ocorre frequentemente em grandes coleções persistentes (como caches), com padrão de design do observador ou variáveis ​​locais de thread. Isso não é teórico, eu mesmo corrigi vários vazamentos de memória na produção. E isso não é anti Java. Eu sou um desenvolvedor JAVA em tempo integral por mais de 5 anos, tenho trabalhado em muitos projetos diferentes. Não reconhecer que você pode ter vazamento de memória em JAVA (ou em todas as outras linguagens existentes) não é fanboyismo, é mais falta de compreensão de como as coisas realmente funcionam.
Nicolas Bousquet
6
Esta questão poderia dispensar o drama e os comentários sobre "fanboyismo", "abalar as crenças de alguém" e coisas do gênero. Esp. já que toda a discussão se resume a "minha definição de memory leaké melhor do que a sua".
LAFK diz Reinstate Monica

Respostas:

44

Você está confundindo diferentes tipos de vazamentos de memória aqui.

Os horríveis vazamentos de memória baseados em gerenciamento de memória explícita acabaram em Java (ou em qualquer outra linguagem baseada em GC). Esses vazamentos são causados ​​pela perda total do acesso aos blocos de memória sem marcá-los como não utilizados.

Os "vazamentos de memória" ainda presentes em Java e em todas as outras linguagens na face do planeta até que o computador possa ler nossas mentes ainda estão conosco, e estarão no futuro próximo. Esses vazamentos são causados ​​pelo código / programador que mantém referências a objetos que tecnicamente não são mais necessários. Esses são bugs fundamentalmente lógicos e não podem ser evitados em nenhuma linguagem usando as tecnologias atuais.

James
fonte
23
O vazamento de memória ocorre simplesmente quando você se esquece de liberar memória. Em Java, isso ocorre quando você se esquece de definir as referências como nulas. Em C ++, isso acontece quando você esquece de ligar gratuitamente. Ambos são casos de vazamento de memória válidos. E o problema fundamental é o mesmo, você programa consome mais e mais memória até que ele eventualmente trave com um erro OutOfMemory.
Nicolas Bousquet
1
Embora seja verdade que nenhuma linguagem pode evitar que o programador cometa tais erros lógicos, também é verdade que alguns desses erros existem no próprio Java SDK (consulte, por exemplo, java.util.logging.Levelque contém uma estática privada ArrayListna qual todos os objetos que são construídos são colocados na construção e dos quais nunca são removidos), o que torna mais difícil evitá-los ao programar em Java do que em alguma outra linguagem que não contenha tais falhas
Jules
7
Acho que o OP estava perguntando sobre vazamentos de memória de objetos que realmente são inacessíveis, como na resposta aceita da pergunta vinculada. O vazamento de memória causado pelo carregamento de classe de threads. -1
qbt937
1
Também é concebível que a análise estática possa determinar se as referências continuam existindo após sua vida útil - sem a necessidade de leitura da mente.
Kyle Strand de
1
@Amrit Não, o coletor de lixo coleta memória à qual você não tem mais referências. Não há como saber se está OK remover algo para o qual você ainda tem uma referência.
Raphael Schmitz
19

É muito possível que os programas Go apresentem vazamentos de memória. A implementação atual do Go tem um coletor de lixo de marcação e varredura simples. Isso é apenas uma solução temporária e não um coletor de lixo de longo prazo. Veja esta página para mais informações. Olhe sob o cabeçalho Go Garbage Collector. Essa página ainda tem um link para o código da versão atual, se você quiser.

Poindexter
fonte
1
Um dos problemas do coletor de marcação e varredura em Java é o fracionamento de memória. Embora não seja tecnicamente uma memória, pode ser uma perda de memória disponível para o aplicativo.
Peter Lawrey
9

Um 'vazamento de memória' ocorre quando um pedaço de memória que o programador pensava que seria liberado não é liberado. Isso pode acontecer em qualquer idioma, lixo coletado ou não. A causa comum em linguagens de GC é reter uma referência adicional à memória.

“As linguagens não causam vazamentos de memória, os programadores causam vazamentos de memória”.

DJClayworth
fonte
8

Coleta de lixo ou não, você pode escrever um programa que tenha vazamentos de memória em Java, Go ou qualquer outra linguagem na maior parte.

A coleta de lixo tira parte do fardo do programador, mas não evita totalmente os vazamentos.

jzd
fonte
4
Eu sei eu sei. Estou falando especificamente sobre os vazamentos de memória sutis que existem em Java, mesmo o Java difícil foi, em seu início, comercializado como uma linguagem onde vazamentos de memória não existem graças ao GC .
SintaxeT3rr0r
4
Desculpe, não ficou claro. Você disse que "muitos programas Java têm vazamentos de memória (sutis ou não)".
jzd
3

Você está misturando níveis de abstração aqui: os vazamentos de memória são devido a bugs na biblioteca (onde os objetos fazem referência uns aos outros embora cadeias de 'a contém referência a b', bem como uma compensação na implementação do coletor de lixo entre eficiência e precisão. Quanto tempo você deseja gastar para descobrir esses loops? Se você gastar o dobro, poderá detectar loops com o dobro do tempo.

Portanto, o problema de vazamento de memória não é específico da linguagem de programação, não há razão para que GO seja melhor ou pior que Java.

florim
fonte
1
Eu não concordo inteiramente. Os vazamentos de memória se devem ao fato de que o Java possibilita atirar no próprio pé e não está necessariamente relacionado a bug de bibliotecas. Muitos programadores escrevem programas que lenta mas seguramente vazam memória em Java e isso é culpa deles, não das bibliotecas. Além disso, se precisamente o Java GC está fazendo uma troca de tempo / possível vazamento, Go está fazendo as mesmas trocas?
SintaxeT3rr0r
1
e a questão realmente não é "quanto tempo quero gastar para descobrir esses loops?" A questão é "Quanto tempo os mandatos de especificações que o Go GC gasta em tais loops" , que IMHO é uma questão interessante.
SintaxeT3rr0r
16
As cadeias de referência cíclicas não impedem a coleta de lixo em Java.
Andy Thomas