Dziwne zwalnianie pamięci

0

Cześć. Uruchamiam aplikację. Na początku w pamięci zajmuje 12 MB z hakiem. Otwieram pewne okno. Pamięć wzrasta do 74 MB. Zamykam okno, a w form_closing usuwam wszystkie obiekty zadeklarowane globalnie w tym oknie w następujący sposób:

obiekt.Dispose();
obiekt = null

Oczywiście nie wszstkie obiekty posiadają Dispose(np. DispatcherTimer). Rozumiem, że wtedy nie muszę się o nie martwić? Na koniec dodatkowo wykonuję GC.Collect().

O dziwo tak naprawdę tylko zwolnienie dwóch obiektów(Emgu capture i Emgu haarCascade) powoduje widoczne zmniejszenie pamięci. W każdym razie po zamknięciu tego okna, aplikacja zajmuje ponad 50 MB!
Co ciekawe, jeśli drugi raz otworzę to okno, aplikacja zajmuje już ponad 80 MB i z sekundy na sekundę rośnie.

Wszystkie lokalne obiekty tworzę za pomocą using, tzn:

using(ob = new Obiekt())
{
//operacje
} 

O co tu chodzi?

1

Wszystkie lokalne obiekty tworzę za pomocą using
Wszystkie to znaczy jakie? Każdego stringa? do using należy wrzucać w zasadzie tylko obiekty, które trzymają jakieś zewnętrzne zasoby, np. otwarcie pliku, połączenie z serwerem lub bazą, itp.

Na koniec dodatkowo wykonuję GC.Collect().
Raczej niepotrzebnie.

Chyba za dużo mieszasz z tą pamięcią, raczej przeszkadzając collectorowi niż pomagając.

W większości przypadków pod .Net z pamięcią nie należy robić nic. A te kilkadziesiąt megabajtów to zajmować niestety i tak będzie.

0
Azarien napisał(a)

Wszystkie lokalne obiekty tworzę za pomocą using
Wszystkie to znaczy jakie? Każdego stringa? do using należy wrzucać w zasadzie tylko obiekty, które trzymają jakieś zewnętrzne zasoby, np. otwarcie pliku, połączenie z serwerem lub bazą, itp.

Nie, no tylko obiekty IDisposible.

Na koniec dodatkowo wykonuję GC.Collect().
Raczej niepotrzebnie.</quote>
Okazuje się, że po tym mam mniejsze zajęcie pamięci

W większości przypadków pod .Net z pamięcią nie należy robić nic. A te kilkadziesiąt megabajtów to zajmować niestety i tak będzie.

Tak też i ja myślałem. Ale żeby przed otwarciem okna było 12, po 70, a po zamknięciu okna 50? A potem coraz więcej z każdym następnym otwarciem? Teraz analizuję ten kod, znalazłem jednego dataseta póki co, którego nie zwolniłem, ale on nie miał aż tyle danych.

0

W jaki sposób sprawdzasz ile pamięci zajmuje program? Nawet po zwolnieniu pamięci CLR nie koniecznie musi tą pamięć od razu oddać systemowi, bo nie ma takiej potrzeby. System też nie musi od razu zwolnić tej pamięci.

0

Może problem jest z tym Emgu? Bo samo Windows Forms raczej nie jest tak pamięciożerne.

1

Tak też i ja myślałem. Ale żeby przed otwarciem okna było 12, po 70, a po zamknięciu okna 50? A potem coraz więcej z każdym następnym otwarciem?

Podejrzewam po prostu to:
http://msdn.microsoft.com/en-us/library/windows/desktop/cc441804%28v=vs.85%29.aspx
Working Set != Faktyczne zużycie pamięci.
Inaczej mówiąc, to że menadżer zadań pokazuje xxx kb zajętej pamięci to nie znaczy że tyle faktycznie proces potrzebuje.

0

Ile jest warte 50 MB RAM? Złotówkę?

1

Dla dzisiejszych komputerów 50MB to pierdnięcie. Garbage collector nawet nie zwraca uwagi na takie drobnostki (ale pamięta o nich, czeka tylko aż się uzbiera więcej). Przynajmniej takie jest podejście M$.

Poza tym zasoby są zwalniane wtedy, kiedy zaczyna ich brakować w systemie, a nie na wyrost. Jest to bardziej optymalna strategia gdyż sama (de)alokacja jest dość kosztowna czasowo.

0
adf88 napisał(a)

Dla dzisiejszych komputerów 50MB to pierdnięcie. Garbage collector nawet nie zwraca uwagi na takie drobnostki (ale pamięta o nich, czeka tylko aż się uzbiera więcej). Przynajmniej takie jest podejście M$.

Poza tym zasoby są zwalniane wtedy, kiedy zaczyna ich brakować w systemie, a nie na wyrost. Jest to bardziej optymalna strategia gdyż sama (de)alokacja jest dość kosztowna czasowo.

OK, czyli po prostu się nie przejmować, że nie wraca do 12MB

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