Czy Go podlega tym samym subtelnym wyciekom pamięci, co Java?

89

Oto fakty:

  • język Go ma zbieracz śmieci.

  • Java ma kolekcję elementów bezużytecznych

  • wiele programów Java ma (subtelne lub nie) wycieki pamięci

Jako przykład programu Java, który ma wycieki pamięci (nie dla osób o słabym sercu, pytanie może wstrząsnąć twoimi przekonaniami), zobacz tutaj mały program Java o nazwie Tomcat, który ma nawet przycisk „znajdź przecieki”: Czy jest sposób uniknąć wycieków pamięci po wdrożeniu w Tomcat?

Zastanawiam się więc: czy programy napisane w Go będą wykazywać ten sam rodzaj (subtelnych lub nie) wycieków pamięci, które wykazują niektóre programy napisane w Javie?

Składnia T3rr0r
źródło
29
„wiele programów Java ma (subtelne lub nie) wycieki pamięci”, czy masz jakieś dowody na ten „fakt”, czy jest to tylko temat do rozmowy.
Peter Lawrey
17
@Webinator: Myślę, że powinieneś podać przykład jednego z tych „subtelnych wycieków pamięci”, które ma „wiele” programów Java. O ile nie zgłaszasz błędu w odśmiecaniu pamięci, jedynym sposobem na wyciek pamięci w czystej Javie jest zatrzymanie odwołań, których już nie używasz, np. Umieszczając obiekty w kolekcji i nigdy nie usuwając ich z tej kolekcji. Jeśli jest to rodzaj przecieku, do którego się odnosisz, to żaden język na świecie nie ochroni przed nimi, w tym Go.
JeremyP
14
Oto przecieki pamięci, o których mówiłem (+200 głosów za, odpowiedzi z + 150 głosów, wyjaśniono wiele rzeczywistych wycieków pamięci Java): stackoverflow.com/questions/6470651/ ...
SkładniaT3rr0r
6
Oczywiście programy JAVA mają przecieki pamięci, po prostu zapomnij ustawić jakieś odniesienie do null, gdy nie będziesz ich dłużej potrzebować. Występuje często w dużych trwałych kolekcjach (takich jak pamięci podręczne), ze wzorcem projektowym obserwatora lub zmiennymi lokalnymi wątku. To nie jest teoria, sam naprawiłem kilka wycieków pamięci podczas produkcji. I to nie jest anty Java. Jestem pełnoetatowym programistą JAVA od ponad 5 lat, pracowałem nad wieloma różnymi projektami. Brak rozpoznania, że ​​możesz mieć wyciek pamięci w JAVA (lub we wszystkich innych istniejących językach) nie jest fanboyizmem, jest raczej brakiem zrozumienia, jak naprawdę działają.
Nicolas Bousquet
6
To pytanie mogłoby się obejść bez dramatu i komentarzy o „fanboyizmie”, „potrząsaniu czyimś przekonaniem” i tym podobnych. Esp. ponieważ cała dyskusja sprowadza się do stwierdzenia, że ​​„moja definicja memory leakjest lepsza niż twoja”.
LAFK mówi Przywróć Monikę

Odpowiedzi:

44

Mylisz tutaj różne rodzaje wycieków pamięci.

Ohydne wycieki pamięci oparte na jawnym zarządzaniu pamięcią zniknęły w Javie (lub jakimkolwiek innym języku opartym na GC). Przecieki te są spowodowane całkowitą utratą dostępu do fragmentów pamięci bez oznaczania ich jako nieużywanych.

„Wycieki pamięci” wciąż obecne w Javie i każdym innym języku na powierzchni planety, dopóki komputer nie będzie w stanie odczytać naszych myśli, wciąż są z nami i będą w dającej się przewidzieć przyszłości. Przecieki te są spowodowane przez kod / programistę przechowującego odniesienia do obiektów, które nie są już technicznie potrzebne. Są to zasadniczo błędy logiczne i nie można im zapobiec w żadnym języku przy użyciu obecnych technologii.

James
źródło
23
Wyciek pamięci występuje po prostu wtedy, gdy zapomnisz zwolnić pamięć. W Javie dzieje się tak, gdy zapomnisz ustawić odniesienia na null. W C ++ dzieje się tak, jeśli zapomnisz zadzwonić za darmo. Oba są prawidłowymi przypadkami wycieku pamięci. Podstawowy problem jest taki sam, program zużywa coraz więcej pamięci, aż w końcu ulegnie awarii z błędem OutOfMemory.
Nicolas Bousquet
1
Chociaż prawdą jest, że żaden język nie może zapobiec popełnieniu takich błędów logicznych przez programistę, prawdą jest również, że niektóre takie błędy istnieją w samym Java SDK (patrz, na przykład, java.util.logging.Levelktóry zawiera prywatną statyczną, ArrayListw której wszystkie takie obiekty są umieszczone na konstrukcji iz którego nigdy nie są usuwane), przez co trudniej jest ich uniknąć przy programowaniu Javy niż w jakimś innym języku, który nie ma takich wad
Jules
7
Myślę, że OP pytał o wycieki pamięci obiektów, które naprawdę są nieosiągalne, jak w zaakceptowanej odpowiedzi na połączone pytanie. Wyciek pamięci spowodowany ładowaniem klasy z wątków. -1
qbt937
1
Można również sobie wyobrazić, że analiza statyczna mogłaby określić, czy odniesienia istnieją po ich użytecznym okresie życia - nie jest wymagane czytanie w myślach.
Kyle Strand
1
@Amrit Nie, moduł odśmiecania pamięci zbiera pamięć, do której nie masz już odniesień. Nie ma możliwości dowiedzenia się, czy można usunąć coś, do czego nadal masz odniesienie.
Raphael Schmitz
19

Jest bardzo możliwe, że programy Go będą wykazywać wycieki pamięci. Bieżąca implementacja Go ma prostego garbage collectora typu mark-and-sweep. Jest to zamierzone tylko jako rozwiązanie tymczasowe i nie jest przeznaczone jako długoterminowy odśmiecacz. Zobacz tę stronę, aby uzyskać więcej informacji. Spójrz pod nagłówek Go Garbage Collector. Ta strona ma nawet link do kodu dla aktualnej wersji, jeśli masz na to ochotę.

Poindexter
źródło
1
Jednym z problemów kolektora znaczników i wymiarów w Javie jest frakcjonowanie pamięci. Chociaż technicznie nie jest to pamięć, może to oznaczać utratę pamięci dostępnej dla aplikacji.
Peter Lawrey
9

„Wyciek pamięci” występuje wtedy, gdy fragment pamięci, który według programisty zostanie uwolniony, nie zostanie zwolniony. Może się to zdarzyć w dowolnym języku, bez względu na to, czy zostały zebrane czy nie. Typową przyczyną w językach GC jest zachowanie dodatkowego odniesienia do pamięci.

„Języki nie powodują wycieków pamięci, programiści powodują wycieki pamięci”.

DJClayworth
źródło
8

Wyrzucanie elementów bezużytecznych, czy nie, możesz napisać program, który w większości przypadków ma wycieki pamięci w Javie, Go lub jakimkolwiek innym języku.

Garbage Collection odciąża programistę, ale nie zapobiega całkowicie wyciekom.

jzd
źródło
4
Wiem wiem. Mówię konkretnie o subtelnych wyciekach pamięci, które istnieją w Javie, nawet trudna Java była na początku sprzedawana jako język, w którym wycieki pamięci nie istnieją dzięki GC .
Składnia T3rr0r
4
Przepraszam, że nie było jasne. Powiedziałeś, że „wiele programów Java ma (subtelne lub nie) wycieki pamięci”.
jzd
3

Mieszasz tutaj poziomy abstrakcji: przecieki pamięci są spowodowane błędami w bibliotece (gdzie obiekty odwołują się do siebie poprzez łańcuchy `` a hold referencja do b ''), a także kompromis w implementacji garbage collectora między wydajnością a dokładność. Ile czasu chcesz poświęcić na znalezienie takich pętli? Jeśli wydasz dwa razy więcej, będziesz w stanie wykryć pętle dwukrotnie dłuższe.

Zatem problem wycieku pamięci nie jest specyficzny dla języka programowania, nie ma powodu, aby GO sam w sobie był lepszy lub gorszy niż Java.

floren
źródło
1
Nie do końca się z tym zgadzam. Wycieki pamięci wynikają z tego, że Java umożliwia strzelanie sobie w stopę i niekoniecznie jest to związane z błędem bibliotek. Wielu programistów pisze programy, które powoli, ale z pewnością przeciekają pamięć w Javie i to jest ich wina, a nie bibliotek. Ponadto, jeśli dokładnie Java GC dokonuje kompromisu między czasem a możliwym wyciekiem, czy Go dokonuje tych samych kompromisów?
Składnia T3rr0r
1
a pytanie naprawdę nie brzmi "ile czasu chcę spędzić na szukaniu takich pętli?" Pytanie brzmi: "Ile czasu wymaga specyfikacja Go GC spędza na takich pętlach" , co jest interesującym pytaniem IMHO.
Składnia T3rr0r
16
Cykliczne łańcuchy referencyjne nie zapobiegają usuwaniu elementów bezużytecznych w Javie.
Andy Thomas