Jak ważne jest usunięcie wycieków pamięci?

19

Odkryłem przez Valgring, że niektóre programy GTK + przeciekają pamięć. Jak ważne jest usunięcie tych wycieków? To znaczy, często te programy działają bardzo dobrze, ale z drugiej strony nigdy nie można być pewnym, czy ktoś chce skopiować część nieszczelnego kodu do innego programu. I nie jestem pewien, czy idea programów GTK + polega na szybkiej pracy i dlatego są przecieki.

Więc jeśli czasami znajduję wyciek pamięci w programie typu open source, czy powinienem to naprawić, czy występują na przykład problemy z wydajnością, a zatem oryginalnym pomysłem programistów było napisanie małego, nieszczelnego kodu?

Jaakko Seppälä
źródło
17
Wycieki pamięci są zawsze niepożądane. Reprezentują zasoby, których cały system nie może wykorzystać, w tym program hosta, dopóki program się nie zakończy.
recursion.ninja
Istnieje wystarczająca liczba narzędzi / bibliotek, które zajmują się śledzeniem wycieków pamięci. Jest to warte wysiłku, ponieważ użycie interfejsu API po twojej stronie może być nieprawidłowe.
Joop Eggen
1
Na marginesie - valgrind jest świetny, ale może zgłaszać pewne fałszywe alarmy (widziałem je w GObject).
Maciej Piechotka,
Obliczenia zależą od przetwarzania i pamięci: pierwsza to kod, a druga to przestrzeń, w której działa. Jeśli nie można ufać, że nie wyrzucisz własnego pokoju, jak możesz oczekiwać, że użyje go do czegoś pożytecznego?
imallett
1
„Zawsze koduj tak, jakby osoba, która kończy utrzymywanie Twojego kodu, była brutalnym psychopatą, który wie, gdzie mieszkasz”.
Jesse C. Slicer

Odpowiedzi:

6

To, jak ważne jest usunięcie wycieków pamięci, zależy od powagi problemu i ważne, co jeszcze musisz zrobić. Z mojego doświadczenia wynika, że ​​niewielkie wycieki pamięci są raczej łagodne dla większości aplikacji. Czas trwania sesji aplikacji komputerowej zwykle nie jest wystarczająco długi, aby zauważyć jakiekolwiek pogorszenie z powodu niewielkiego wycieku pamięci.

Jeśli piszesz serwer, który działa 24 godziny na dobę, 7 dni w tygodniu, małe wycieki pamięci mogą się z czasem sumować i stać się poważnym problemem. Ale dlatego wiele firm planuje ponowne uruchamianie serwerów codziennie lub co tydzień. Wysiłek związany z wykrywaniem wycieków pamięci jest często nadmierny w stosunku do tego, co można uzyskać, dlatego łatwiej jest regularnie uruchamiać ponownie serwery i przechodzić do ważniejszych rzeczy.

Moher
źródło
2
Nigdy nie pracowałem w firmie, która co tydzień uruchamiała swój serwer ... nawet rzadziej codziennie. Zgadzam się, że koszt usunięcia wycieku może być zbyt wysoki, aby go naprawić, ale takie nastawienie nie jest dobre IMO
Rémi
@ Rémi Większość, jeśli nie wszystkie, serwery gier MMO robią to zwykle co tydzień.
Sjoerd,
35

W przypadku programów krótko działających wycieki pamięci nie są tak ważne; system operacyjny odzyska wszystko po wygaśnięciu, ale może spowodować, że inne zasoby nie zostaną zwolnione.

Jakkolwiek krótki bieg jest względny, wyciek może wymknąć się spod kontroli w ciągu kilku godzin lub gromadzić się przez tygodnie niezauważony.

Moja rada to zgłosić błąd w module śledzącym z proponowaną poprawką, jeśli prowadzący go to obchodzi.

Ważny jest również rodzaj wycieku. Możliwe, że alokacja, która przecieka, jest jednorazową alokacją, w której programista umyślnie polegał na systemie operacyjnym w celu oczyszczenia. To da fałszywy pozytyw na Valgrind.

maniak zapadkowy
źródło
4
W większości się zgadzam. Sugeruję jednak podkreślić znaczenie wycieku pamięci. Wycieki pamięci nie powinny być zbyt szybkie i mogą powodować interesujące „funkcje” aplikacji.
Vladimir Kocjancic
@VladimirKocjancic: +1 za „funkcję”
Emilio Garavaglia
1
Chcę tylko podkreślić, że komputer jest w stanie wykonać to przetwarzanie jeden na milion kilka milionów razy dość szybko. Nigdy tego nie zapomnij. Jeśli więc weźmiecie to pod uwagę, zgadzam się z tą odpowiedzią, ponieważ tak naprawdę to zależy od programu. W przypadku systemu osadzonego, który ma działać bez interwencji człowieka, wycieki pamięci są śmiertelne. W przypadku implementacji „grep” prawdopodobnie nie przejmowałbyś się tym mniej.
Dunk
2
@Dunk: Zależy: jeśli przejdziesz grepprzez bardzo duży plik, a twój program wycieknie kilka bajtów dla każdej linii wejściowej, możesz zabraknąć pamięci.
Giorgio
0

W mojej wprawdzie dogmatycznej opinii na ten temat nie ma usprawiedliwienia dla fizycznych wycieków, przynajmniej w żadnej bibliotece, która ma być szeroko stosowana. Chciałbym więc popsuć programistów GTK +, dopóki sami tego nie naprawią.

Jest to wystarczająco trywialne, aby biblioteka zarejestrowała atexitwywołania zwrotne w celu zwolnienia pamięci, którą przydzieli, przynajmniej po zwolnieniu. Jeśli chce uniknąć kosztu mnóstwa drobnych przydziałów, nie powinno ich robić w ogóle.

Nawet najbardziej leniwy program, który chce tylko przydzielić mnóstwo małych kawałków pamięci na raz, mógłby użyć prostego sekwencyjnego alokatora, który po prostu usuwa całą pamięć podczas zamykania. Jeśli alokator nie chce nawet zajmować się wyrównywaniem, może po prostu uzupełnić każdą pojedynczą porcję, którą gromadzi, do maksymalnych granic wyrównywania. Jeśli byłby w stanie skorzystać z krótszych czasów wyłączania, nie uwalniając osobno wszystkich tych małych kawałków pamięci, to równie dobrze zyska symetrycznie w zamian za trywialny wysiłek, stosując taki sekwencyjny alokator, który łączy pamięć w prosty sekwencyjny sposób z znacznie szybsze alokacje niżmalloci bardziej przyjazne dla pamięci podręcznej wzorce pamięci, tylko po to, by wszystkie duże bloki ciągłej pamięci były pulowane przez alokator, kiedy biblioteka jest gotowa. Cała biblioteka ma do czynienia wtedy jest zastąpienie ich mallocpołączenia, dla których nie przejmuj się freez czymś takim seq_malloc, a rozmowy seq_purgew atexitzwrotnego, aby zwolnić całą pamięć przydzieloną na zwalnianego.

W przeciwnym razie ta nieprzyjemna biblioteka zaśmieca wiadomości w narzędziach do wykrywania wycieków pamięci, które musisz teraz odfiltrować. Co gorsza, jeśli nie odfiltrujesz ich systematycznie, mogą one ukryć wycieki we własnej aplikacji, a twoi koledzy mogą rozwinąć nawyk przeoczania ich, zmniejszając przede wszystkim użyteczność narzędzi do wykrywania wycieków, zapobiegając w ten sposób Twojemu zespołowi wypychanie nieszczelnego kodu. Jest to obrzydliwe i brzydkie, a przede wszystkim nie uważam, aby argumenty przemawiające za robieniem tego celowo były przekonujące, biorąc pod uwagę, jak banalne jest użycie powyższego rozwiązania.

Logiczne wycieki (bardziej złożony rodzaj, przed którym nawet zbieranie śmieci nie może się zabezpieczyć) są bardziej złożonym problemem i tam mogę znaleźć uzasadnienie dla krótkotrwałych programów mających logiczne wycieki, o ile usuwają całą pamięć, na którą przydzielają zamknięcie systemu, ponieważ wymaga wiele przemyśleń na temat zarządzania zasobami, aby uniknąć logicznych wycieków (prawdopodobnie bardziej w językach, w których występuje GC). Ale nie znajduję żadnej uzasadnionej wymówki, aby unikać fizycznych wycieków, biorąc pod uwagę, jak banalne są unikanie nawet w najbardziej leniwych kontekstach.

W każdym razie przynajmniej odfiltruję przecieki w valgrind, aby przynajmniej nie zadzierały ze zdolnością twojego zespołu do wykrycia twojego.


źródło
1
Zastanawiam się, czy przecieki mają coś wspólnego z „kodowaniem łodzi”?
0

FWIW, jeśli użytkownik zgłosiłby wyciek w aplikacji, nad którą pracuję, byłbym bardzo skłonny to naprawić (szczególnie, gdyby w raporcie o błędzie zawierał kod poprawki!). To powiedziawszy, może się to nie zdarzyć natychmiast, jeśli wyciek był niewielki, a inne problemy były bardziej naglące (powiedzmy, że błąd występował często). Ale na pewno byłbym wdzięczny i ostatecznie staram się to naprawić. Powinieneś zdecydowanie dać im znać. Będą albo docenić to i pracować nad naprawą (najprawdopodobniej), albo nie będą się tym przejmować, a wszystko to będzie kosztować trochę czasu.

użytkownik1118321
źródło