Go est-il sujet aux mêmes fuites de mémoire subtiles que Java?

89

Voici les faits:

  • le langage Go a un garbage collector.

  • Java a un garbage collection

  • beaucoup de programmes Java ont des fuites de mémoire (subtiles ou non)

Comme exemple de programme Java qui a des fuites de mémoire (pas pour les âmes sensibles, la question peut ébranler vos croyances), voyez ici à propos d'un petit programme Java appelé Tomcat qui a même un bouton "rechercher des fuites": Y a - t-il un moyen pour éviter les fuites de mémoire d'annulation de déploiement dans Tomcat?

Je me demande donc: les programmes écrits en Go présenteront-ils le même type de fuites de mémoire (subtiles ou non) que certains programmes écrits en Java?

SyntaxeT3rr0r
la source
29
"beaucoup de programmes Java ont des fuites de mémoire (subtiles ou non)" avez-vous des preuves de ce "fait" ou est-ce juste un point de discussion.
Peter Lawrey
17
@Webinator: Je pense que vous devez donner un exemple de l'une de ces "fuites de mémoire subtiles" que "beaucoup de" programmes Java ont. À moins que vous ne réclamiez un bogue dans le ramasse-miettes, la seule façon de perdre de la mémoire en Java pur est de conserver les références que vous n'utilisez plus, par exemple en mettant des objets dans une collection et en ne les supprimant jamais de cette collection. Si c'est le genre de fuite dont vous parlez, aucune langue au monde ne les protégera, y compris Go.
JeremyP
14
Voici les fuites de mémoire dont je parlais (+200 votes positifs, réponses avec +150 votes positifs, beaucoup de fuites de mémoire Java réelles expliquées): stackoverflow.com/questions/6470651/…
SyntaxeT3rr0r
6
Bien sûr, les programmes JAVA ont des fuites de mémoire, oubliez simplement de définir une référence sur null lorsque vous en avez plus besoin. Se produit fréquemment dans de grandes collections persistantes (comme les caches), avec un modèle de conception d'observateur ou des variables locales de thread. Ce n'est pas théorique, j'ai corrigé moi-même plusieurs fuites mémoire en production. Et ce n'est pas anti Java. Je suis un développeur JAVA à plein temps depuis plus de 5 ans, j'ai travaillé sur de nombreux projets différents. Ne pas reconnaître que vous pouvez avoir une fuite de mémoire dans JAVA (ou dans tout autre langage existant) n'est pas du fanboyisme, c'est plus un manque de compréhension du fonctionnement réel des choses.
Nicolas Bousquet
6
Cette question pourrait se passer du drame et des commentaires sur le "fanboyisme", "ébranler les croyances de quelqu'un", etc. Esp. puisque toute la discussion se résume à "ma définition de memory leakest meilleure que la vôtre".
LAFK dit Réintégrer Monica

Réponses:

44

Vous confondez différents types de fuites de mémoire ici.

Les fuites de mémoire odieuses basées sur la gestion explicite de la mémoire ont disparu en Java (ou dans tout autre langage basé sur GC). Ces fuites sont causées par la perte totale d'accès aux morceaux de mémoire sans les marquer comme inutilisés.

Les «fuites de mémoire» toujours présentes en Java et dans tous les autres langages à la surface de la planète jusqu'à ce que l'ordinateur puisse lire nos pensées sont toujours avec nous, et le seront dans un avenir prévisible. Ces fuites sont causées par le code / programmeur gardant des références à des objets qui ne sont techniquement plus nécessaires. Ce sont des bogues fondamentalement logiques et ne peuvent être évités dans aucun langage utilisant les technologies actuelles.

James
la source
23
La fuite de mémoire se produit simplement lorsque vous oubliez de libérer de la mémoire. En Java, cela se produit lorsque vous oubliez de définir les références sur null. En C ++, cela arrive si vous oubliez d'appeler gratuitement. Les deux sont des cas de fuite de mémoire valides. Et le problème fondamental est le même, votre programme consomme de plus en plus de mémoire jusqu'à ce qu'il finisse par planter avec une erreur OutOfMemory.
Nicolas Bousquet
1
S'il est vrai qu'aucun langage ne peut empêcher le programmeur de faire de telles erreurs logiques, il est également vrai que certaines de ces erreurs existent dans le SDK Java lui-même (voir, par exemple, java.util.logging.Levelqui contient une statique privée ArrayListdans laquelle tous ces objets construits sont placés sur la construction, et dont ils ne sont jamais supprimés), ce qui rend plus difficile de les éviter lors de la programmation Java que dans un autre langage qui ne contient pas de telles failles
Jules
7
Je pense que l'OP posait des questions sur les fuites de mémoire d'objets qui sont vraiment inaccessibles, comme dans la réponse acceptée à la question liée. La fuite de mémoire causée par le chargement de classe à partir des threads. -1
qbt937
1
Il est également concevable que l'analyse statique puisse déterminer si les références continuent d'exister au-delà de leur durée de vie utile - aucune lecture mentale n'est requise.
Kyle Strand
1
@Amrit Non, le garbage collector collecte la mémoire à laquelle vous n'avez plus de références. Il n'a aucun moyen de savoir s'il est acceptable de supprimer quelque chose auquel vous avez encore une référence.
Raphael Schmitz
19

Il est très possible que les programmes Go présentent des fuites de mémoire. L'implémentation actuelle de Go a un simple ramasse-miettes avec marquage et balayage. Ceci est uniquement conçu comme une solution temporaire et n'est pas destiné à être le ramasse-miettes à long terme. Consultez cette page pour plus d'informations. Regardez sous l'en-tête Go Garbage Collector. Cette page a même un lien vers le code de la version actuelle si vous le souhaitez.

Poindexter
la source
1
L'un des problèmes du collecteur de marques et de balayages en Java est la fragmentation de la mémoire. Bien qu'il ne s'agisse pas techniquement d'une mémoire, il peut s'agir d'une perte de mémoire disponible pour l'application.
Peter Lawrey
9

Une «fuite de mémoire» se produit lorsqu'un morceau de mémoire dont le programmeur pensait qu'il serait libéré n'est pas libéré. Cela peut se produire dans n'importe quelle langue, garbage collection ou non. La cause habituelle dans les langages GC est de conserver une référence supplémentaire à la mémoire.

"Les langages ne provoquent pas de fuites de mémoire, les programmeurs provoquent des fuites de mémoire".

DJClayworth
la source
8

Garbage collection ou non, vous pouvez écrire un programme qui a des fuites de mémoire en Java, Go ou tout autre langage pour la plupart.

Le nettoyage de la mémoire soulage une partie du fardeau du programmeur, mais il n'empêche pas entièrement les fuites.

jzd
la source
4
Je sais je sais. Je parle spécifiquement des fuites de mémoire un peu subtiles qui existent en Java, même si Java était, à ses débuts, commercialisé comme un langage où les fuites de mémoire n'existent pas grâce au GC .
SyntaxeT3rr0r
4
Désolé, ce n'était pas clair. Vous avez dit "beaucoup de programmes Java ont des fuites de mémoire (subtiles ou non)".
jzd
3

Vous mélangez ici les niveaux d'abstraction: les fuites de mémoire sont dues à des bogues dans la bibliothèque (où les objets se référencent entre eux via des chaînes de 'a tient référence à b' ainsi qu'à un compromis dans l'implémentation du ramasse-miettes entre l'efficacité et Combien de temps voulez-vous consacrer à la recherche de telles boucles? Si vous dépensez deux fois plus, vous serez en mesure de détecter les boucles deux fois plus longtemps.

Ainsi, le problème de la fuite de mémoire n'est pas spécifique au langage de programmation, il n'y a aucune raison que GO en soi soit meilleur ou pire que Java.

florin
la source
1
Je ne suis pas entièrement d'accord. Les fuites de mémoire sont dues au fait que Java permet de se tirer une balle dans le pied et ce n'est pas forcément lié au bug des bibliothèques. Beaucoup de programmeurs écrivent des programmes qui perdent lentement mais sûrement de la mémoire en Java et c'est leur propre faute, pas la faute des bibliothèques. De plus, si le GC Java fait précisément un compromis temps / fuite possible, Go fait-il les mêmes compromis?
SyntaxeT3rr0r
1
et la question n'est vraiment pas "combien de temps est-ce que je veux passer à découvrir de telles boucles?" La question est "Combien de temps les spécifications exigent que le GC Go passe sur de telles boucles" , ce qui, à mon humble avis, est une question intéressante.
SyntaxeT3rr0r
16
Les chaînes de référence cycliques n'empêchent pas le garbage collection en Java.
Andy Thomas