Visual Leak Detector, wycieki w C#

0

Jest coś podobnego ale dla C# ? Bo wszędzie tylko piszą o tym jak to podłączyć do projektów VS C++, a jak korzystać z tego dla projektów C# ?

0

Raczej sie nie da, bo to chyba natywna biblioteka z tego co widze

0

By się coś takiego przydało :( Bo mam problemy z wyciekiem. Nie rozumiem do końca tego które obiekty są usuwane przez GC. Mówi się że GC usuwa te obiekty "do których nie ma referencji dostepnych w kodzie". Co znaczy że nie ma referencji ? Czy oznacza to że dla fragmentu obiekt1 = obiekt2 nie da się oczyścić obiekt2 bo jest referencja do niego ? Ale obiekt1.wlasciwosc1 = obiekt2.wlasciwosc1 to już nie referencja jak mniemam i przy takim zapisie obiekt2 da się już oczyścić.
A co znaczy "nie ma osiągalnych w kodzie referencji do danego obiektu" ??
Zauważyłem że nawet jak się wymusza GC.Collect to i tak on sobie to robi "jak chce" raz usunie mniej a raz więcej. Wygląda na to że mamy w C# kiepski wpływ na procesy zwalniania pamięci.
Czytałem parę artykułów o GC ale nadal ciężko mi dojść do tego jak to działa / gdzie jest wyciek w moim programie. (Nie używam NIGDZIE przypisania typu obiekt1 = obiekt2, eventy odłączam stosując obiekt1.Click -= new Event.....)

0

-= new Event? odłączasz nowo utworzony handler? i jak to ma działać według Ciebie?

0

I on śmie mówić, że ktoś źle coś zaprojektował...

0

Tak też się dziwiłem - ale to działa w sensie że odłącza obsługę zdarzenia (sprawdziłem na timerze - tick timera nie wchodził już do obsługi przerawania). W takim razie jak inaczej to zrobić ? Może obiekt.zdarzenie += null ? (to sprawdzałem - nie rozłącza). A tworzyć osobne EventHandlery i je odłączać (bo wtedy moznaby uzyć obiekt -= danyEventHandler) jest dla mnie nie do przyjęcia.

BTW:

I on śmie mówić, że ktoś źle coś zaprojektował...
gdzie ja coś takiego napisałem ? Jeżeli nie chcesz pomóc to ok, ale trochę się czepiasz niepotrzebnie.

0

W c# przeciez pojecie wycieku nie ma prawa istniec... GC sam zwalnia obiekty i sam decyduje kiedy to zrobi.

0

Wyciek ma prawo istnieć i istnieje. Pomijając obiekty, które korzystają z niezarządzanych zasobów takie jak Bitmap, Font i podobne, to jeśli trzymasz gdzieś referencję do obiektu, który już dawno powinien przestać istnieć i zostać usunięty a nie jest i taki obiekt przechodzi do kolejnych Generacji (a w końcu do 3ciej) i np. nigdy przez cały okres działania aplikacji nie jest usuwany to jak dla mnie to jest jak najbardziej wyciek i takie sytuacje mają miejsce.
To jest mit o tym, że w C#/.NET nie można mieć wycieków.

0

Podobnie gdy zostawisz przypisany event do elementu. Jak stworzysz na jego miejsce nowy (nie użyjesz przed tym dispose) to tamten poprzedni nie będzie mógł być usunięty. A przecież takie sytuacje występują, np gdy zmieniasz/tworzysz przyciski na formie. Jak program ma działać non-stop to takich sytuacji będzie sporo.

0
ŁF napisał(a)

-= new Event? odłączasz nowo utworzony handler? i jak to ma działać według Ciebie?

to dziala, poniewaz Delegate ma przeciazony Equals, ktory porownuje Target i Method.

( new EventHandler(this.onClick).Equals(new EventHandler(this.onClick)) ) == true

i na tym porownaniu bazuja metody Add i Remove w implementacjach listy wywolan Eventow (defacto, nie ma takich i sa tylko invocationlists delegatow.. ale to szczegol)

+= new EventHandler(this.onClick) powoduje przypiecie
-= new EventHandler(this.onClick) powoduje odpiecie

nie wierzysz - sprawdz. albo uzyj Reflectora.

ps. ah - i tak sie sklada, ze Eventy bardzo czesto NALEZY odpinac w w momencie kiedy juz ich nie potrzeba, poniewaz EventHandlery prowadzace do metod {mojego} obiektu, podpiete pod jakies rzeczy dlużej żyjące, np. globalne czy systemowe, calkowicie realnie powoduja przedluzenie czasu zycia {mojego} obiektu ponad to czego mozna by sie spodziewac po nullowaniu referencji do niego..

johny_bravo napisał(a)

W c# przeciez pojecie wycieku nie ma prawa istniec... GC sam zwalnia obiekty i sam decyduje kiedy to zrobi.

istieje - moga wyciekac Handle i inne zasoby 'niezarzadzane'

0
quetzalcoatl napisał(a)

ps. ah - i tak sie sklada, ze Eventy bardzo czesto NALEZY odpinac w w momencie kiedy juz ich nie potrzeba, poniewaz EventHandlery prowadzace do metod {mojego} obiektu, podpiete pod jakies rzeczy dlużej żyjące, np. globalne czy systemowe, calkowicie realnie powoduja przedluzenie czasu zycia {mojego} obiektu ponad to czego mozna by sie spodziewac po nullowaniu referencji do niego..

A jak to działa, jeśli do zdarzenia jest podpięta metoda anonimowa?

quetzalcoatl napisał(a)
johny_bravo napisał(a)

W c# przeciez pojecie wycieku nie ma prawa istniec... GC sam zwalnia obiekty i sam decyduje kiedy to zrobi.

istieje - moga wyciekac Handle i inne zasoby 'niezarzadzane'

Ja kiedyś napisałem przeglądarkę plików graficznych i wycieki były ogromne :)

0
somekind napisał(a)
quetzalcoatl napisał(a)

ps. ah - i tak sie sklada, ze Eventy bardzo czesto NALEZY odpinac w w momencie kiedy juz ich nie potrzeba, poniewaz EventHandlery prowadzace do metod {mojego} obiektu, podpiete pod jakies rzeczy dlużej żyjące, np. globalne czy systemowe, calkowicie realnie powoduja przedluzenie czasu zycia {mojego} obiektu ponad to czego mozna by sie spodziewac po nullowaniu referencji do niego..

A jak to działa, jeśli do zdarzenia jest podpięta metoda anonimowa?

metoda nigdy nie jest animowa. wszystko co jest 'anonimowe' jest wygenerowywane przez kompilator. do kazdej metody anonimowej dorabiana jest klasa delegatu, tworzona jest metoda normalna, i sa one uzywane tak jakbys napisal +=new EventHandler(blah). a wszystko to nazywane jest w stylu "__metoda_costam<>" [ostre nawiasy SĄ czescia nazwy!] czyli tak, zebys nie mial szans na kolizje z Twoimi normalnymi nazwami. polecam napisac sobie jakas mala klaske z automatycznym property w stylu int blah{get;set;}, z jakas mala metoda ktora podepnie gdzies eventhandler (o,e)=>{}, oraz z jakims malym wyrazeniem linq to objects w stylu from x in new List<obj> where x!=null select x; --- skompilowac i obejrzec pod reflectorem. Magia pryśnie :))

szybki edit: okeeeej, sa metody "anonimowsze" --- mozna za pomoca Reflection.Emit wygenerowac assembly z kodem wygenerowanym w runtime'ie. bedzie to kod 'anonimowy' z punktu widzenia pliku .cs ktory teraz piszesz. ale nadal wszystko nie bedzie anonimowe - dynamiczna assembly bedzie mialo nazwe, dynamiczna klasa w nim rowniez, dynamiczna metoda - rowniez - choćby po to, byś mogl ja przez reflection odebrac i odpalic...

nie ma anonimowosci w (inter)Net'cie :)

0

No ok. Czyli nazwa "anonimowy" to tylko kolejny chwyt marketingowy M$.
To jak w takim razie odpiąć taką metodę, skoro nie wiem jak ona się nazywa?

0

left as an exercise to the reader ;]

0
somekind napisał(a)

To jak w takim razie odpiąć taką metodę, skoro nie wiem jak ona się nazywa?

Google prawde Ci powie.

0

No ok, ale muszę trzymać referencję ("nazwanego delegata"), żeby móc potem odpiąć.
Takiego czegoś już nie odepnę, prawda?

txtCena.TextChanged += delegate { this.Text = txtCena.Text; };
0

Wątpię, żeby nie odpięcie delegata dołączonego jak wyżej powodowało wyciek. Można sprawdzić, ale po pierwsze - przecież chyba by o tym pomyśleli, skoro metody anonimowe i wyrażenia lambda są już bardzo powszechnie stosowane. Po drugie, jeśli kasowany jest delegate, bo nie ma do niego referencji, to prawdopodobnie wszystkie metody razem z nim.

0

problem tkwi w DRUGA STRONE:

  • masz obiekt X
  • obiekt X alokuje tablice miliona bajtow i zapamietuje ja w swoim field'zie
  • podpinasz metode X.OnClick do np. glownej formatki programu, do jakiegos eventu
  • ...costam...
  • gubisz obiekt X. nie jest Ci potrzebny, zapominasz o nim.

Ale:

  • formatka glowna, event jakistam, trzyma wciaz tamten podpiety EventHandler
  • EventHandler ma w sobie prop. Method -> X:Metoda(), oraz Target ->> X.. tak, EventHandler pamieta obiekt, a ten zas wciaz trzyma tablice..

wniosek?
zgubiles obiekt X, ale jest on nadal trzymany.
natomiast jak odepniesz ten eventhandler przed zgubieniem obiektu X, to gc bedzie mialo szanse go sprzatnac.

ah - i wazne - nawet X.Dispose() nie zrobi automatycznego odpiecia eventhandlerow prowadzacych do niego. Nawet jak wywolasz X.Dispose(), jego EventHandlery nadal moga zostac wywolane. Dlatego w Dispose nalezy odpinac wszystkie znane handlery ktore ten obiekt zarejestrowal, chyba ze nie zalezy nam na jego faktycznym sprzatnieciu oraz jego odpalanie po Dispose jest bezpieczne..

0
quetzalcoatl napisał(a)

problem tkwi w DRUGA STRONE:

Niekoniecznie problem, bo to często bywa bardzo pomocne, nie musisz trzymać dodatkowo tysiąca referencji do X, kiedy potrzebne są tylko eventhandlery. Korzystam z tego bardzo często.

quetzalcoatl napisał(a)

ah - i wazne - nawet X.Dispose() nie zrobi automatycznego odpiecia eventhandlerow prowadzacych do niego. Nawet jak wywolasz X.Dispose(), jego EventHandlery nadal moga zostac wywolane. Dlatego w Dispose nalezy odpinac wszystkie znane handlery ktore ten obiekt zarejestrowal, chyba ze nie zalezy nam na jego faktycznym sprzatnieciu oraz jego odpalanie po Dispose jest bezpieczne..

Ale jeśli liczba referencji do X wynosi 0 , czyli obiekt może być oznaczony przez GC jako "do usunięcia", to nawet jeśli X.Dispose() nie wyczyści handlerów, to w jaki sposób chcesz je wywołać, skoro nie masz już do nich dostępu? Potrzebujesz referencji do X, albo bezpośrednio do handlera, a wtedy to już jest przypadek j.w. Jeśli wywołasz tylko Dispose() to nie usuniesz referencji do X, więc można jeszcze różne rzeczy z tym X zrobić, w tym - wywołać handlery, jeśli nie zostały usunięte.

0

po pierwsze, wez moze przeczytaj caly watek od poczatku i postaraj sie zrozumiec o co w nim chodzilo

Ale jeśli liczba referencji do X wynosi 0 , czyli obiekt może być oznaczony przez GC jako "do usunięcia", to nawet jeśli X.Dispose() nie wyczyści handlerów

po drugie - jesli istnieja jakiekolwiek EventHandler'y do X, to liczba referencji nie ma prawa wyniesc zero. wynika to wprost z dzialania eventow oraz Eventhandlerow, i tez mozna to wyczytac wprost z tego co napisalem w poscie ktory zacytowales. Po przeczytaniu watku, przeczytaj wiec moj post dodatkowe kilka razy..

po trzecie - sprobuj sam. wlacz VS, napisz pare prostych klas z eventhandlerami i popatrz co kiedy zostaje zwalniane i czy eventy ktore Ty podepniesz (pod cos np. statycznego) rzeczywiscie nie beda mialy efekty 'wycieku'

1 użytkowników online, w tym zalogowanych: 0, gości: 1