Anatomia " wycieku pamięci"

W perspektywie. NET:

  • Co to jest wyciek pamięci ?
  • Jak można ustalić, czy aplikacja przecieka? Jakie są efekty?
  • Jak można zapobiec wyciekowi pamięci?
  • jeśli Twoja aplikacja ma wyciek pamięci, czy zniknie, gdy proces zakończy się lub zostanie zabity? A może wycieki pamięci w aplikacji wpływają na inne procesy w systemie nawet po zakończeniu procesu?
  • a co z niezarządzanym kodem dostępnym przez COM Interop i / lub P/Invoke?
Author: Zoe, 2008-08-01

15 answers

Najlepsze wyjaśnienie, jakie widziałem, znajduje się w rozdziale 7 DARMOWEGO Foundations of Programming e-book.

Zasadniczo w . Net następuje wyciek pamięci, gdy obiekty odniesienia są zakorzenione, a zatem nie mogą być zbierane. Dzieje się tak przypadkowo, gdy przechowujesz odniesienia wykraczające poza zamierzony zakres.

Będziesz wiedział, że masz przecieki, gdy zaczniesz wychodzić z pamięci lub zużycie pamięci wykracza poza to, czego się spodziewasz (PerfMon ma ładny liczniki pamięci).

Zrozumienie modelu pamięci.Net jest najlepszym sposobem na uniknięcie tego. Konkretnie, zrozumienie, jak działa garbage collector i jak działają odniesienia-ponownie odsyłam do rozdziału 7 e-booka. Należy również pamiętać o typowych pułapkach, prawdopodobnie najczęściej są to wydarzenia. Jeśli obiekt a jest zarejestrowany na zdarzenie na obiekcie B , to obiekt A pozostanie w pobliżu, dopóki obiekt B nie zniknie, ponieważ B posiada odniesienie do A . Rozwiązaniem jest wyrejestrowanie wydarzeń po zakończeniu.

Oczywiście, dobry profil pamięci pozwoli Ci zobaczyć wykresy obiektów i zbadać zagnieżdżanie/odwoływanie się do obiektów, aby zobaczyć, skąd pochodzą odniesienia i jaki obiekt główny jest odpowiedzialny (profil mrówek red-gate, JetBrains dotMemory, memprofiler są naprawdę dobrymi wyborami, lub możesz użyć tylko tekstu WinDbg i {5]}SOS {6]}, ale nie zdecydowanie polecam produkt komercyjny / wizualny, chyba że jesteś prawdziwym guru).

Uważam, że niezarządzany kod podlega typowym wyciekom pamięci, z wyjątkiem tego, że współdzielone odniesienia są zarządzane przez garbage collector. Mogę się mylić co do ostatniego punktu.

 109
Author: Karl Seguin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-14 20:34:56

Ściśle mówiąc, wyciek pamięci pochłania pamięć, która nie jest już używana przez program.

"No longer used" ma więcej niż jedno znaczenie, może oznaczać "no more reference to it", czyli całkowicie nie do odzyskania, lub może oznaczać, odwołuje się, odzyskuje, nieużywane, ale program i tak zachowuje odniesienia. Tylko później odnosi się do. Net dla doskonale zarządzanych obiektów . Jednak nie wszystkie klasy są doskonałe i w pewnym momencie podstawowa niezarządzana implementacja może wyciek zasobów na stałe dla tego procesu.

We wszystkich przypadkach aplikacja zużywa więcej pamięci niż jest to konieczne. Efekty uboczne, w zależności od ilości wycieku, mogą przejść od zera, do spowolnienia spowodowanego nadmierną kolekcją, do serii WYJĄTKÓW pamięci i wreszcie błędu krytycznego, po którym następuje wymuszone zakończenie procesu.

Wiesz, że aplikacja ma problem z pamięcią, gdy monitorowanie pokazuje, że coraz więcej pamięci jest przydzielane do procesu po każdym cykl zbierania śmieci . W takim przypadku albo zachowujesz zbyt dużo pamięci, albo jakaś niezarządzana implementacja przecieka.

W przypadku większości wycieków zasoby są odzyskiwane po zakończeniu procesu, jednak niektóre zasoby nie zawsze są odzyskiwane w pewnych precyzyjnych przypadkach, z tego powodu znane są uchwyty kursora GDI. Oczywiście, jeśli masz mechanizm komunikacji międzyprocesowej, pamięć przydzielona w innym procesie nie zostanie uwolniona, dopóki ten proces go nie uwolni lub / align = "left" /

 33
Author: Coincoin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-01 17:52:46

Myślę, że" co to jest wyciek pamięci "i" jakie są skutki " pytania zostały już dobrze odpowiedział, Ale chciałem dodać kilka rzeczy na inne pytania...

Jak zrozumieć, czy Twoja aplikacja przecieka

Jednym z ciekawych sposobów jest otwarcie perfmon i dodanie śladów dla # bajtów we wszystkich stertach i # Gen 2 kolekcjach , w każdym przypadku patrząc tylko na proces. Jeśli wykonanie określonej funkcji powoduje, że suma bajtów zwiększ, a pamięć zostanie przydzielona po następnej kolekcji 2 Gen, można powiedzieć, że funkcja wycieka pamięć.

Jak zapobiegać

Wydano inne dobre opinie. Dodam tylko, że być może najczęściej pomijaną przyczyną wycieków pamięci.NET jest dodawanie procedur obsługi zdarzeń do obiektów bez ich usuwania. Obsługa zdarzeń dołączona do obiektu jest formą odniesienia do tego obiektu, więc uniemożliwi gromadzenie nawet po wszystkich innych referencje zniknęły. Zawsze pamiętaj, aby odłączyć procedury obsługi zdarzeń (używając składni -= W C#).

Przeciek zniknie po zakończeniu procesu, a co z COM interop?

Po zakończeniu procesu cała pamięć zmapowana do jego przestrzeni adresowej jest odzyskiwana przez system operacyjny, w tym wszelkie obiekty COM obsługiwane z bibliotek DLL. Stosunkowo rzadko obiekty COM mogą być obsługiwane z oddzielnych procesów. W takim przypadku po zakończeniu procesu nadal możesz być odpowiedzialny za pamięć przydzielone w dowolnych procesach serwera COM, z których korzystałeś.

 29
Author: Martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-26 15:51:52

Zdefiniowałbym wycieki pamięci jako obiekt, który nie zwalnia całej pamięci przydzielonej po jej zakończeniu. Odkryłem, że może się to zdarzyć w Twojej aplikacji, Jeśli używasz Windows API i COM (tj. niezarządzanego kodu, który ma błąd lub nie jest zarządzany poprawnie), w frameworku i w komponentach innych firm. Odkryłem również, że nie tiding się po użyciu niektórych przedmiotów, takich jak długopisy, może powodować problem.

Ja osobiście cierpiałem z powodu WYJĄTKÓW pamięci, które mogą być spowodowane ale nie są wyłącznie wyciekami pamięci w aplikacjach. net. (OOM może również pochodzić z przypinania patrz Przypinanie artykulu ). Jeśli nie otrzymujesz błędów OOM lub musisz potwierdzić, czy powoduje to wyciek pamięci, jedynym sposobem jest profilowanie aplikacji.

Postaram się również zapewnić:

A) wszystko, co implementuje Idisposable, jest usuwane za pomocą finally block lub instrukcji using, w tym pędzli, długopisów itp.(niektórzy twierdzą, że ustawić wszystko do niczego dodatkowo)

B) wszystko, co ma metodę close, jest ponownie zamykane za pomocą polecenia finally lub using (chociaż znalazłem polecenie using nie zawsze jest zamykane w zależności od tego, czy zadeklarowałeś obiekt poza instrukcją using)

C) jeśli używasz kodu niezarządzanego / windows API ' s, że są one rozpatrywane poprawnie po. (niektóre mają metody czyszczenia, aby zwolnić zasoby)

Mam nadzieję, że to pomoże.

 19
Author: John,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-01 17:57:14

Jeśli chcesz zdiagnozować wyciek pamięci w. NET, sprawdź te linki:

Http://msdn.microsoft.com/en-us/magazine/cc163833.aspx

Http://msdn.microsoft.com/en-us/magazine/cc164138.aspx

Artykuły te opisują, jak utworzyć zrzut pamięci procesu i jak go przeanalizować, aby najpierw określić, czy wyciek nie jest zarządzany lub zarządzany, a jeśli jest zarządzany, jak dowiedzieć się, skąd pochodzi.

Microsoft ma też nowszą narzędzie wspomagające generowanie zrzutów awaryjnych, zastępujące ADPlus, zwane DebugDiag.

Http://www.microsoft.com/downloads/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&displaylang=en

 19
Author: Eric Z Beard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-19 10:30:03

Korzystanie z CLR Profiler od Microsoftu http://www.microsoft.com/downloads/details.aspx?familyid=86ce6052-d7f4-4aeb-9b7a-94635beebdda&displaylang=en to świetny sposób na określenie, które obiekty przechowują pamięć, jaki przepływ wykonania prowadzi do ich utworzenia, a także monitorowanie, które obiekty żyją gdzie na stercie (fragmentacja, LOH, itp.).

 15
Author: Nick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-16 19:54:30

Najlepsze wyjaśnienie, jak działa garbage collector jest w Jeff Richters CLR poprzez C# książka, (Ch. 20). Czytanie tego daje świetną podstawę do zrozumienia, jak obiekty utrzymują się.

Jedną z najczęstszych przyczyn przypadkowego zakorzenienia obiektów jest podpięcie zdarzeń poza klasą. Jeśli podłączysz zdarzenie zewnętrzne

Np.

SomeExternalClass.Changed += new EventHandler(HandleIt);

I zapomnij odpiąć do niego, gdy się go pozbędziesz, wtedy ktoś z zewnątrz ma ref do twojej klasy.

Jak wspomniano powyżej, SciTech memory profiler jest doskonały w pokazaniu korzeni obiektów, które podejrzewasz, że wyciekają.

Ale jest też bardzo szybki sposób, aby sprawdzić konkretny typ, wystarczy użyć WnDBG (możesz nawet użyć tego w VS.NET natychmiastowe okno podczas załączenia):

.loadby sos mscorwks
!dumpheap -stat -type <TypeName>

Teraz zrób coś, co Twoim zdaniem usunie obiekty tego typu (np. zamknij okno). Przydaje się tutaj mieć gdzieś przycisk debugowania, który będzie uruchamiany System.GC.Collect() kilka razy.

Wtedy Uruchom !dumpheap -stat -type <TypeName> jeszcze raz. Jeśli liczba nie spadła, lub nie spadła tak bardzo, jak się spodziewasz, to masz podstawę do dalszego dochodzenia. (Dostałem tę wskazówkę z seminarium, które wygłosił Ingo Rammer ).

 15
Author: Gus Paul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-19 10:25:19

Myślę, że w zarządzanym środowisku, wyciekiem byłoby trzymanie niepotrzebnego odniesienia do dużej części pamięci wokół.

 14
Author: Bernard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-01 15:19:25

Dlaczego ludzie myślą, że wyciek pamięci w. Net nie jest taki sam, jak każdy inny wyciek?

Wyciek pamięci jest wtedy, gdy dołączasz do zasobu i nie puszczasz go. Możesz to zrobić zarówno w kodowaniu zarządzanym, jak i niezarządzanym.

Jeśli chodzi o.NET i inne narzędzia programistyczne, pojawiły się pomysły na zbieranie śmieci i inne sposoby minimalizacji sytuacji, które spowodują wyciek Twojej aplikacji. Ale najlepszą metodą zapobiegania wyciekom pamięci jest to, że musisz zrozumieć swoje bazowy model pamięci i sposób działania na używanej platformie.

Przekonanie, że GC i inna Magia posprzątają Twój bałagan, to krótka droga do wycieków pamięci i będzie trudna do znalezienia później.

Podczas kodowania niezarządzanego, Zwykle upewniasz się, że sprzątasz, wiesz, że zasoby, które przejmiesz, będą twoim obowiązkiem posprzątać, a nie woźnego.

W. Net z drugiej strony, Wiele osób myśli, że GC wszystko posprząta. Dobrze., robi to dla ciebie, ale musisz się upewnić, że tak jest. . NET zawija wiele rzeczy, więc nie zawsze wiesz, czy masz do czynienia z zarządzanym lub niezarządzanym zasobem i musisz upewnić się, z czym masz do czynienia. Obsługa czcionek, zasobów GDI, active directory, baz danych itp. To zazwyczaj rzeczy, na które należy zwrócić uwagę.

W kategoriach zarządzanych położę szyję na tekst, który mówi, że kiedyś odejdzie Proces jest zabijany/usuwany.

Widzę Wiele osób ma to jednak, i naprawdę mam nadzieję, że to się skończy. Nie możesz poprosić Użytkownika o zakończenie aplikacji, aby posprzątać swój bałagan! Spójrz na przeglądarkę, która może być IE, FF itp, Następnie otwórz, powiedzmy, Google Reader, Niech zostanie na kilka dni, i zobacz, co się dzieje.

Jeśli następnie otworzyć inną kartę w przeglądarce, surfować do jakiejś witryny, a następnie zamknąć kartę, która hostowała drugą stronę, która spowodowała wyciek przeglądarki, czy uważasz, że przeglądarka zwolni pamięć? Nie tak z IE. On my komputer IE z łatwością zje 1 GiB pamięci w krótkim czasie (około 3-4 dni), jeśli użyję Google Reader. Niektóre newsy są jeszcze gorsze.

 11
Author: neslekkiM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-06 09:04:13

Myślę, że w zarządzanym środowisku, a przeciek byłby, gdybyś trzymał niepotrzebne odniesienie do dużego kawałka pamięci wokół.

Absolutnie. Również, nie za pomocą .Metoda Dispose () na obiektach jednorazowych może spowodować wycieki mem. Najprostszym sposobem jest użycie bloku using, ponieważ jest on wykonywany automatycznie .Dispose () na końcu:
StreamReader sr;
using(sr = new StreamReader("somefile.txt"))
{
    //do some stuff
}

I jeśli tworzysz klasę, która używa niezarządzanych obiektów, jeśli nie implementujesz IDisposable prawidłowo, możesz powodować wycieki pamięci dla użytkowników twojej klasy.

 10
Author: Seibar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-05 22:47:49

Zgodzę się z Bernardem co do tego, że w. Net byłby przeciek mem.

Możesz profilować aplikację, aby zobaczyć jej zużycie pamięci i określić, że jeśli zarządza dużą ilością pamięci, gdy nie powinno być, możesz powiedzieć, że ma wyciek.

W kategoriach zarządzanych położę szyję na linii, aby powiedzieć, że to odejdzie, gdy proces zostanie zabity / usunięty.

Niezarządzany kod jest własną bestią i jeśli w nim istnieje wyciek, będzie podążał za standardowym mem. definicja przecieku.

 10
Author: Pat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-30 21:14:09

Wszystkie wycieki pamięci są rozwiązywane przez zakończenie programu.

Wyciek wystarczającej ilości pamięci i System Operacyjny może podjąć decyzję o rozwiązaniu problemu w Twoim imieniu.

 9
Author: Josh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-04 14:09:47

Należy również pamiętać, że. NET ma dwie sterty, z których jedna jest stertą dużych obiektów. Uważam, że na tej stercie umieszczane są obiekty o wielkości około 85 tysięcy lub większej. Ta sterta ma inne zasady życia niż zwykła sterta.

Jeśli tworzysz duże struktury pamięci (słownik lub Lista), rozważnie byłoby poszukać dokładnych reguł.

Jeśli chodzi o odzyskiwanie pamięci po zakończeniu procesu, chyba że uruchomiony Win98 lub jego odpowiedniki, wszystko jest zwalniane z powrotem do systemu operacyjnego na zakończenie. Jedynymi wyjątkami są rzeczy, które są otwarte między procesami, a inny proces nadal ma otwarty zasób.

COM obiekty mogą być trudne tho. Jeśli zawsze używasz wzoru IDispose, będziesz bezpieczny. Ale natknąłem się na kilka zespołów interop, które implementują IDispose. Kluczem jest to, aby zadzwonić Marshal.ReleaseCOMObject Kiedy skończysz z tym. Obiekty COM nadal używają standardowego zliczania referencji COM.

 7
Author: Joel Lucsy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-26 15:52:26

Znalazłem . Net Memory Profiler bardzo dobrą pomoc przy znajdowaniu wycieków pamięci w .Net. nie jest darmowy jak Microsoft CLR Profiler, ale jest szybszy i bardziej do punktu moim zdaniem. A

 6
Author: Lars Truijens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-20 18:39:25

Jedna z definicji brzmi: nie można zwolnić nieosiągalnej pamięci, która nie może być już przydzielona do nowego procesu podczas wykonywania procesu alokacji. Najczęściej można go wyleczyć za pomocą technik GC lub wykryć za pomocą zautomatyzowanych narzędzi.

Aby uzyskać więcej informacji, odwiedź http://all-about-java-and-weblogic-server.blogspot.in/2014/01/what-is-memory-leak-in-java.html.

 1
Author: hemant kurmi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-15 16:00:47