Go è soggetto alle stesse sottili perdite di memoria di Java?


91

Ecco i fatti:

  • la lingua Go ha un garbage collector.

  • Java ha una raccolta dei rifiuti

  • molti programmi Java hanno (impercettibili o meno) perdite di memoria

Come esempio di un programma Java che ha perdite di memoria (non per i deboli di cuore, la domanda potrebbe scuotere le tue convinzioni), guarda qui su un piccolo programma Java chiamato Tomcat che ha anche un pulsante "trova perdite": C'è un modo evitare perdite di memoria di non distribuzione in Tomcat?

Quindi mi chiedo: i programmi scritti in Go mostreranno lo stesso tipo di perdite di memoria (sottili o meno) che mostrano alcuni programmi scritti in Java?


29
"molti programmi Java hanno (sottili o meno) perdite di memoria" hai qualche prova di questo "fatto" o è solo un punto di discussione.
Peter Lawrey

17
@Webinator: Penso che sia necessario fornire un esempio di una di queste "sottili perdite di memoria" che "molti" programmi Java hanno. A meno che tu non stia reclamando un bug nel garbage collector, l'unico modo per perdere memoria in Java puro è mantenere i riferimenti che non stai più utilizzando, ad esempio inserendo oggetti in una raccolta e non rimuovendoli mai da quella raccolta. Se questo è il tipo di fuga di notizie a cui ti riferisci, nessuna lingua al mondo proteggerà da esse, incluso Go.
JeremyP

14
Qui ci sono le perdite di memoria di cui parlavo (+200 upvotes, risponde con +150 upvotes, un sacco di effettive perdite di memoria Java spiegato): stackoverflow.com/questions/6470651/...
SyntaxT3rr0r

6
Ovviamente i programmi JAVA hanno perdite di memoria, basta dimenticare di impostare qualche riferimento su null quando non ne hai più bisogno. Si verifica frequentemente in grandi raccolte persistenti (come le cache), con pattern di progettazione dell'osservatore o variabili locali del thread. Questo non è teorico, ho corretto da solo diverse perdite di memoria in produzione. E questo non è anti Java. Sono uno sviluppatore JAVA a tempo pieno da più di 5 anni, ho lavorato a molti progetti diversi. Non riconoscere che si può avere una perdita di memoria in JAVA (o in tutti gli altri linguaggi esistenti) non è fanboy, è più mancanza di comprensione di come funzionano davvero le cose.
Nicolas Bousquet

6
Questa domanda potrebbe fare a meno del dramma e dei commenti sul "fanboyismo", "scuotere le convinzioni di qualcuno" e simili. Esp. poiché l'intera discussione si riduce a "la mia definizione di memory leakè migliore della tua".
LAFK dice Reinstate Monica

Risposte:


44

Stai confondendo diversi tipi di perdite di memoria qui.

Le odiose perdite di memoria basate sulla gestione della memoria esplicita sono sparite in Java (o in qualsiasi altro linguaggio basato su GC). Queste perdite sono causate dalla perdita completa dell'accesso a blocchi di memoria senza contrassegnarli come inutilizzati.

Le "fughe di memoria" ancora presenti in Java e in ogni altro linguaggio sulla faccia del pianeta fino a quando il computer non potrà leggere le nostre menti sono ancora con noi, e lo saranno per il prossimo futuro. Queste perdite sono causate dal codice / programmatore che mantiene riferimenti a oggetti che tecnicamente non sono più necessari. Questi sono fondamentalmente bug logici e non possono essere prevenuti in nessuna lingua utilizzando le tecnologie attuali.


23
La perdita di memoria è semplicemente quando ti dimentichi di liberare memoria. In Java ciò si verifica quando ci si dimentica di impostare i riferimenti su null. In C ++ succede se ti dimentichi di chiamare gratis. Entrambi sono casi di perdita di memoria validi. E il problema fondamentale è lo stesso, il programma consuma sempre più memoria fino a quando non si blocca con un errore OutOfMemory.
Nicolas Bousquet

1
Sebbene sia vero che nessun linguaggio può impedire al programmatore di commettere tali errori logici, è anche vero che alcuni di questi errori esistono nello stesso Java SDK (vedere, ad esempio, java.util.logging.Levelche contiene una statica privata ArrayListin cui tutti gli oggetti di questo tipo che sono costruiti sono posto in costruzione e da cui non vengono mai rimossi), il che rende più difficile evitarli durante la programmazione di Java rispetto a qualche altro linguaggio che non contiene tali difetti
Jules

7
Penso che l'OP chiedesse informazioni sulle perdite di memoria di oggetti che sono davvero irraggiungibili come nella risposta accettata alla domanda collegata. La perdita di memoria causata dal caricamento della classe dai thread. -1
qbt937

1
È anche concepibile che l'analisi statica possa determinare se i riferimenti continuano a esistere oltre la loro durata utile, senza necessità di lettura del pensiero.
Kyle Strand

1
@Amrit No, il garbage collector raccoglie la memoria a cui non hai più riferimenti. Non ha modo di sapere se è corretto rimuovere qualcosa a cui si ha ancora un riferimento.
Raphael Schmitz

19

È molto probabile che i programmi Go mostrino perdite di memoria. L'attuale implementazione di Go ha un semplice garbage collector mark-and-sweep. Questo è solo inteso come una soluzione temporanea e non è inteso come il garbage collector a lungo termine. Vedi questa pagina per maggiori informazioni. Guarda sotto l'intestazione Go Garbage Collector. Quella pagina ha anche un collegamento al codice per la versione corrente se sei così incline.


1
Uno dei problemi di mark and sweep collector in Java è il frazionamento della memoria. Sebbene non sia tecnicamente una memoria, può essere una perdita di memoria disponibile per l'applicazione.
Peter Lawrey

9

Una "perdita di memoria" si verifica quando un pezzo di memoria che il programmatore pensava sarebbe stato liberato non viene liberato. Questo può accadere in qualsiasi lingua, raccolta dei rifiuti o meno. La causa comune nei linguaggi GC è il mantenimento di un ulteriore riferimento alla memoria.

"Le lingue non causano perdite di memoria, i programmatori causano perdite di memoria".


8

Garbage collection o no, puoi scrivere un programma che ha perdite di memoria in Java, Go o qualsiasi altro linguaggio per la maggior parte.

Garbage Collection alleggerisce parte del fardello del programmatore ma non previene completamente le perdite.


4
Lo so, lo so. Sto parlando in particolare del genere di sottili perdite di memoria che esistono in Java, anche se Java è stato, all'inizio, commercializzato come un linguaggio in cui non esistono perdite di memoria grazie al GC .
SyntaxT3rr0r

4
Mi dispiace che non fosse chiaro. Hai detto che "molti programmi Java hanno (impercettibili o meno) perdite di memoria".
jzd

3

Stai mescolando i livelli di astrazione qui: le perdite di memoria sono dovute a bug nella libreria (dove gli oggetti si riferiscono l'un l'altro sebbene catene di 'a trattiene il riferimento a b' così come un compromesso nell'implementazione del garbage collector tra efficienza e Quanto tempo vuoi dedicare alla ricerca di tali loop? Se spendi il doppio, sarai in grado di rilevare i loop due volte più a lungo.

Quindi il problema della perdita di memoria non è specifico del linguaggio di programmazione, non c'è motivo per cui GO da solo dovrebbe essere migliore o peggiore di Java.


1
Non sono del tutto d'accordo. Le perdite di memoria sono dovute al fatto che Java consente di spararsi ai piedi e non è necessariamente correlato a bug delle librerie. Molti programmatori scrivono programmi che lentamente ma inesorabilmente perdono memoria in Java e questa è colpa loro, non delle librerie. Inoltre, se proprio il Java GC sta facendo un compromesso tempo / possibile perdita, Go sta facendo gli stessi compromessi?
SyntaxT3rr0r

1
e la domanda in realtà non è "quanto tempo voglio dedicare alla ricerca di tali circuiti?" La domanda è "Quanto tempo le specifiche obbliga il Go GC spendono su tali cicli" , che IMHO è una domanda interessante.
SyntaxT3rr0r

16
Le catene di riferimento cicliche non impediscono la garbage collection in Java.
Andy Thomas
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.