Anatomia „Memory Leak”

głosy
159

W .NET perspektywy:

  • Co to Przeciek pamięci ?
  • Jak można określić, czy swoimi przecieków aplikacji? Jakie są efekty?
  • Jak można zapobiec przeciek pamięci?
  • Jeśli aplikacja ma przeciek pamięci, to odejdzie, gdy proces kończy działanie lub zostanie zabity? Albo czy wycieki pamięci w aplikacji wpływa na inne procesy w systemie nawet po zakończeniu procesu?
  • A co z kodem niezarządzanym dostępne za pośrednictwem modelu COM i / lub P / Invoke?
Utwórz 01/08/2008 o 16:12
źródło użytkownik
W innych językach...                            


15 odpowiedzi

głosy
14

Chyba w środowisku zarządzanym, wyciek byłby pan utrzymywanie niepotrzebnych odniesienie do dużego fragmentu pamięci dookoła.

Odpowiedział 01/08/2008 o 16:19
źródło użytkownik

głosy
9

Ja zgadzam się z Bernardem jak w .NET, co przeciek mem będzie.

Można profil aplikacji, aby zobaczyć jego wykorzystanie pamięci, a także określić, że jeśli jego zarządzania dużo pamięci, gdy nie powinno być można powiedzieć, że ma nieszczelności.

W zarządzanych względem położę moją szyję na linii, aby powiedzieć, że nie odejdzie po zakończeniu procesu zostaje zabity / usunięte.

Kod niezarządzalny jest jego własny bestia i jeśli przeciek istnieje w nim, to zgodnie ze standardową mem. wyciek definicji.

Odpowiedział 01/08/2008 o 16:23
źródło użytkownik

głosy
106

Najlepszym wyjaśnieniem Widziałem to w rozdziale 7 wolnych Podstaw Programowania e-book .

Zasadniczo, w .NET występuje przeciek pamięci, gdy przywoływane obiekty są zakorzenione, a zatem nie mogą być zbierane śmieci. Dzieje się tak przypadkowo trzymać odniesienia poza zamierzony zakres.

Będziesz wiedzieć, że masz przecieki podczas uruchamiania OutOfMemoryExceptions uzyskaniu lub Twój zużycie pamięci sięga poza to, co można się spodziewać ( PerfMon ma ładne liczniki pamięci).

Zrozumienie .NET model pamięci „s jest najlepszym sposobem uniknięcia go. Konkretnie, zrozumienie, jak działa i jak śmieciarza odniesienia pracować - znów odsyłam do rozdziału 7 e-book. Należy także pamiętać o typowych pułapek, prawdopodobnie najczęściej będące wydarzenia. Jeśli obiekt jest zarejestrowany do wydarzenia na obiekcie B , a następnie obiekt A będzie trzymać się aż obiekt B znika ponieważ B posiada odniesienie do . Rozwiązaniem jest wyrejestrować swoje wydarzenia, kiedy skończysz.

Oczywiście, dobry profil pamięci pozwoli Ci zobaczyć wykresy obiektów i zbadać gniazdowania / powoływanie się swoimi obiektami, aby zobaczyć gdzie referencje pochodzą i co korzeń obiekt jest odpowiedzialny ( mrówki czerwone bramy profil , JetBrains dotMemory, memprofiler są naprawdę dobre wybory, czy można korzystać z tekstu tylko WinDbg i SOS , ale bym zalecamy komercyjny produkt / wizualny, chyba że jesteś prawdziwym guru).

Wierzę kod niekontrolowana podlega jego typowych wycieków pamięci, chyba że wspólne odniesienia są zarządzane przez garbage collector. Mogę się mylić o tym ostatnim punkcie.

Odpowiedział 01/08/2008 o 16:28
źródło użytkownik

głosy
32

Ściśle mówiąc, przeciek pamięci zużywa pamięci, która jest „nie jest już używany” przez program.

„Nie jest już używany” ma więcej niż jedno znaczenie, może to oznaczać „nie więcej odniesienie do niej”, czyli całkowicie nie do odzyskania, lub może to oznaczać, odwoływać, zwrotowi, nieużywany ale program przechowuje referencje i tak. Dopiero później dotyczy NET doskonale zarządzanych obiektów . Jednak nie wszystkie zajęcia są idealne, a w pewnym momencie leżące u podstaw niekontrolowana realizacja może wyciekać środki trwałe w tym procesie.

We wszystkich przypadkach, aplikacja zużywa więcej pamięci niż jest to absolutnie potrzebne. Efekty stron, w zależności od ammount wyciekły, mogłaby przejść od zera do spowolnienia spowodowanego przez nadmierne gromadzenie, do szeregu wyjątków pamięci i wreszcie fatalnym błędem następnie wymuszonym zakończeniem procesu.

Wiesz aplikacja ma problem pamięci, gdy monitoring wykazuje, że coraz więcej pamięci jest przydzielona do procesu po każdym cyklu zbierania śmieci . W takim przypadku, są albo utrzymywanie zbyt dużo pamięci, lub jakiś bazowego niekontrolowana realizacja przecieka.

Dla większości wycieków, zasoby są odzyskiwane, gdy proces jest zakończony, jednak niektóre zasoby nie zawsze są odzyskiwane w niektórych szczególnych przypadkach, uchwyty kursora GDI są notorycznie za to. Oczywiście, jeśli masz mechanizm komunikacji między procesami, pamięć przydzielona w drugim procesie nie być uwolniony, dopóki ten proces uwalnia go lub kończy.

Odpowiedział 01/08/2008 o 18:52
źródło użytkownik

głosy
18

Chciałbym określić wycieków pamięci jako obiekt nie zwalniając całą pamięć przydzieloną po jego ukończeniu. Znalazłem to może się zdarzyć w aplikacji, jeśli używasz systemu Windows API i COM (czyli kod niekontrolowana że ma błąd w nim, czy nie jest zarządzana prawidłowo), w ramach oraz w elementach zewnętrznych. Ja również nie znaleziono sprzątania po użyciu pewnych obiektów jak długopisy mogą powodować problem.

Ja osobiście poniosły Spośród Wyjątki pamięci, która może być spowodowane, ale nie wykluczają, aby wycieki pamięci w aplikacjach dot netto. (OOM może również pochodzić od przypinanie zobaczyć przypinanie artical ). Jeśli nie otrzymujesz błędy OOM lub muszą potwierdzić, czy jest to przeciek pamięci powodując wówczas jedynym sposobem jest do profilowania aplikacji.

Chciałbym również spróbować i upewnić się, co następuje:

a) Wszystko który implementuje IDisposable umieszczony jest albo za pomocą bloku finally lub za pomocą oświadczenia te obejmują pędzle, długopisy i inne (niektórzy twierdzą, ustawić wszystko na nic oprócz)

b) Wszystko, co ma ścisły sposób zamyka się ponownie używając końcu lub using (choć znalazłem użyciu nie zawsze blisko zależności jeśli zadeklarowana obiektu poza wykorzystaniem rachunku)

c) Jeśli używasz kodu niezarządzanego / windows API to, że są one traktowane poprawnie po. (Niektóre mają oczyścić metod, aby zwolnić zasoby)

Mam nadzieję że to pomoże.

Odpowiedział 01/08/2008 o 18:57
źródło użytkownik

głosy
9

Wszystkie wycieki pamięci są rozwiązane przez zakończeniem programu.

Wyciek wystarczającej ilości pamięci oraz system operacyjny może zdecydować, aby rozwiązać ten problem w swoim imieniu.

Odpowiedział 04/08/2008 o 15:09
źródło użytkownik

głosy
10

Chyba w środowisku zarządzanym, wyciek byłby pan utrzymywanie niepotrzebnych odniesienie do dużego fragmentu pamięci dookoła.

Absolutnie. Ponadto, nie stosując metodę .Dispose () na przedmioty jednorazowego użytku w razie potrzeby można spowodować mem nieszczelności. Najprostszym sposobem na to jest z wykorzystaniem bloku, ponieważ automatycznie wykonuje .Dispose () na końcu:

StreamReader sr;
using(sr = new StreamReader("somefile.txt"))
{
    //do some stuff
}

A jeśli utworzyć klasę, która korzysta niezarządzanymi przedmioty, jeśli nie jesteś wykonawczych IDisposable poprawnie, może być przyczyną wycieków pamięci dla użytkowników w klasie.

Odpowiedział 05/08/2008 o 23:47
źródło użytkownik

głosy
7

Należy także pamiętać, że .NET ma dwa stosy, jeden jest duży obiekt sterty. Wierzę, że obiekty w przybliżeniu 85k lub większe są umieszczane na tej stercie. Ta kupa ma różne zasady trwałość niż w przypadku zwykłej stercie.

W przypadku tworzenia dużych struktur pamięci (Słownik lub Lista'S) byłoby rozsądne, aby przejść odnośnika co Dokładne zasady są.

Jeśli chodzi o odzyskanie pamięci na zakończenie procesu, chyba że działa to Win98 lub ekwiwalenty, wszystko jest uwalniany z powrotem do systemu operacyjnego na zakończenie. Jedynymi wyjątkami są rzeczy, które są otwierane przekrój proces i inny proces wciąż ma zasób otwarty.

Obiekty COM może być trudne tho. Jeśli zawsze używać IDisposewzór, będziesz bezpieczny. Ale mam natknąć kilka zestawów międzyoperacyjnych, które wdrażają IDispose. Kluczem jest tu zadzwonić Marshal.ReleaseCOMObjectkiedy jesteś z nim zrobić. COM Przedmioty nadal używać standardowego liczenia odniesienia COM.

Odpowiedział 07/08/2008 o 14:17
źródło użytkownik

głosy
18

Jeśli trzeba 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 analizować to tak, że można najpierw ustalić, czy wyciek jest niekontrolowana lub zarządzany, a jeśli to jest zarządzany, w jaki sposób dowiedzieć się, gdzie ona pochodzi.

Microsoft ma również nowszą narzędzie pomocnicze w generujących wysypisk zderzeniowych, aby zastąpić ADPlus, zwany DebugDiag.

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

Odpowiedział 15/08/2008 o 00:16
źródło użytkownik

głosy
28

Myślę, że „to, co jest przeciek pamięci” i „Jakie są skutki” pytania zostały wysłuchane już dobrze, ale chciałem dodać kilka rzeczy na innych pytań ...

Jak zrozumieć, czy swoimi przecieków aplikacyjnych

Ciekawym sposobem jest otwarcie perfmon i dodać ślady na # bajtów we wszystkich stertach i # Gen 2 kolekcjach , w każdym przypadku, patrząc tylko na swoim procesie. W przypadku wykonywania szczególną cechę powoduje całkowite bajtów, aby zwiększyć, a pamięć pozostaje przyznana po następnej Gen 2 kolekcji, można powiedzieć, że funkcja przecieki pamięci.

Jak zapobiegać

Inne dobre opinie zostały podane. Chciałbym tylko dodać, że chyba najczęściej pomijany przyczyną wycieków pamięci .NET jest dodanie obsługi zdarzeń do obiektów bez ich usuwania. Obsługa zdarzeń przypisane do obiektu jest formą odniesienia do tego obiektu, więc uniemożliwi zbieranie nawet gdy wszystkie inne odniesienia poszły. Zawsze należy pamiętać, aby odłączyć obsługi zdarzeń (przy użyciu -=składni w C #).

Czy wyciek odejść, gdy wyjścia procesu, a co o modelu COM?

Gdy wychodzi procesowe, wszystkie pamięci mapowane do jego przestrzeni adresowej jest odzyskiwana przez system operacyjny, w tym wszelkie obiekty COM podawane z DLL. Stosunkowo rzadko, obiekty COM mogą być podawane w osobnych procesach. W tym przypadku, kiedy opuszcza swój proces, może nadal być odpowiedzialny za pamięci przydzielonej w dowolnych procesów serwera COM, które wykorzystywane.

Odpowiedział 15/08/2008 o 17:11
źródło użytkownik

głosy
15

Korzystanie CLR Profiler od Microsoft http://www.microsoft.com/downloads/details.aspx?familyid=86ce6052-d7f4-4aeb-9b7a-94635beebdda&displaylang=en to świetny sposób, aby określić, które obiekty są gospodarstwa pamięć prowadzi przepływu co egzekucyjne do tworzenia tych obiektów, a także monitorowanie które obiekty na żywo, gdzie na sterty (fragmentacja, LOH, itd.).

Odpowiedział 16/08/2008 o 20:54
źródło użytkownik

głosy
6

Znalazłem .NET pamięci Profiler bardzo dobrą pomoc podczas szukania wycieków pamięci w .NET. To nie jest wolny jak Microsoft CLR Profiler, ale jest szybszy i bardziej do punktu, w mojej opinii. ZA

Odpowiedział 20/08/2008 o 19:39
źródło użytkownik

głosy
14

Najlepszym wyjaśnieniem tego, jak działa garbage collector jest Jeff Richters CLR za pośrednictwem C # książki (rozdz. 20). Czytając to daje wielką uziemienie dla zrozumienia, jak obiekty utrzymywać.

Jedną z najczęstszych przyczyn kibicowania obiektów przypadkowo jest podpinania wydarzenia outisde klasy. Jeśli spięcie zdarzenie zewnętrzne

na przykład

SomeExternalClass.Changed += new EventHandler(HandleIt);

i zapomnij odpiąć do niego po zbyć, następnie SomeExternalClass ma wg swojej klasie.

Jak wspomniano powyżej, pamięć profiler SciTech jest doskonała na pokazując korzenie obiektów podejrzewasz przeciekają.

Ale jest też bardzo szybki sposób sprawdzić konkretny typ jest po prostu użyć WnDBG (można nawet użyć tego w najbliższym oknie VS.NET podczas załączeniu):

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

Teraz zrobić coś, co naszym zdaniem będzie wyrzucać obiektów tego typu (np zamknąć okno). Jest poręczny, żeby mieć gdzieś przycisk debugowania, który będzie uruchamiany System.GC.Collect()kilka razy.

Następnie uruchom !dumpheap -stat -type <TypeName>ponownie. Jeżeli numer nie przejdzie, czy nie zejść jak można się spodziewać, to masz podstawę do dalszych badań. (Mam to wskazówka z seminarium podane przez Ingo Rammer ).

Odpowiedział 27/08/2008 o 15:12
źródło użytkownik

głosy
10

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

Przeciek pamięci po podłączeniu do zasobu i nie pozwolić jej odejść. Można to zrobić zarówno zarządzane i niekontrolowana kodowania.

Jeśli chodzi o .NET i inne narzędzia programistyczne, nie było pomysłów na zbieranie śmieci i inne sposoby minimalizowania sytuacje, które uczynią Państwa wycieku aplikacji. Ale najlepszą metodą zapobiegania wycieków pamięci jest to, że trzeba zrozumieć swój podstawowy model pamięci, i jak to wszystko działa na platformie używasz.

Wierząc, że GC i inne magiczne będzie oczyścić bałagan jest krótka droga do wycieków pamięci i będzie trudno znaleźć później.

Podczas kodowania niekontrolowana, zwykle upewnij się, aby posprzątać, wiesz, że środki można podjąć trzymać, będzie odpowiedzialny oczyścić, nie dozorcy.

W .NET Z drugiej strony, wiele osób uważa, że ​​GC będzie posprzątać wszystko. Cóż, to nie jakiś dla ciebie, ale trzeba się upewnić, że tak jest. NET ma zawinąć wiele rzeczy, więc nie zawsze wiem, czy masz do czynienia z zasobu zarządzanego lub niekontrolowana, i trzeba się upewnić, co, co masz do czynienia. Obchodzenie czcionek, zasobów GDI, Active Directory, bazy danych itp jest zazwyczaj rzeczy, które trzeba zwrócić uwagę.

W zarządzanych względem położę moją szyję na linii, aby powiedzieć, że nie odejdzie po zakończeniu procesu zostaje zabity / usunięte.

Widzę wiele osób ma ten, choć i ja naprawdę nadzieję, że to się nie skończy. Nie można zwrócić się do użytkownika, aby zakończyć aplikację, aby oczyścić swój bałagan! Spójrz na przeglądarkę, która może być IE, FF itp, wtedy otwarty, powiedzmy, Google Reader, niech to pozostanie na kilka dni, i patrzeć na to, co się dzieje.

Jeśli następnie otworzyć kolejną kartę w przeglądarce, surfowania w pewnym miejscu, a następnie zamknij kartę, że gospodarzem drugą stronę, wykonaną wyciek przeglądarki, myślisz, że przeglądarka będzie zwolnić pamięć? Nie tak z IE. Na moim komputerze IE będzie łatwo jeść 1 GiB pamięci w krótkim okresie czasu (około 3-4 dni), jeśli użyć Google Reader. Niektóre newspages są jeszcze gorsze.

Odpowiedział 01/09/2008 o 13:19
źródło użytkownik

głosy
1

Jedna z definicji jest: Nie można zwolnić nieosiągalny pamięć, która nie może już być przydzielony do nowego procesu w trakcie realizacji procesu alokacji. Może on być w większości utwardzona za pomocą technik, GC lub wykrywany przez automatyczne narzędzia.

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

Odpowiedział 27/08/2014 o 16:22
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more