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?
Odpowiedzi:
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.
źródło
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.
źródło
grep
przez bardzo duży plik, a twój program wycieknie kilka bajtów dla każdej linii wejściowej, możesz zabraknąć pamięci.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
atexit
wywoł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ż
malloc
i 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 ichmalloc
połączenia, dla których nie przejmuj sięfree
z czymś takimseq_malloc
, a rozmowyseq_purge
watexit
zwrotnego, 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
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.
źródło