Destruktor w C++/CLI

0

Tworzę sobie dynamicznie zakładkę (i kilka kontrolek na niej) i w pewnej funkcji ją usuwam ale nie wiem czy dobrze robię bo spoglądając w menadżera zadań pamięci nie ubywa (przed utworzeniem zakładki było 12 600KB, po utworzeniu 13 800KB, po skasowaniu również 13 800KB). Kod w skrócie można zapisać tak:

TabPage^ tabPage;
tabPage = (gcnew System::Windows::Forms::TabPage());
tabPage->~TabPage();

Czy źle używam destruktora? Czy może powinno się użyć jakiejś specjalnej metody? Na pewno jest coś nie tak, program ma mieć dynamiczne zakładki ale skoro pamięci wciąż przybywa to użytkownik po kilkunastu operacjach może otrzymać błąd o braku dostępnej pamięci, a to już będzie nie fajnie.

0

W tym przypadku pamięć jest zarządzana automatycznie przez wirtualną maszynę .net, na to większego wpływu nie masz. Poczytaj o garbage collector.

0

Kolega wyżej ma rację.

Obiekty w zarządzanym C++ są niszczone przez garbage collector. Sam nie możesz ich zniszczyć mimo, że wywołasz destruktor.

Jeśli w obiekcie zarządzanym przechowujesz jakieś dane niezarządzane, to ich zwalnianie musisz umieszczać w "finalizatorach"

http://msdn.microsoft.com/en-us/library/ms177197(v=vs.90).aspx

pzdr
squash

0

Destruktor (ze znakiem ~) klasy zarządzanej w C++/CLI to tak naprawdę lukier składniowy na przeciążoną metodę Dispose() — wewnątrz której możemy zwalniać jakieś zasoby, ale sam „destruowany” obiekt nie zostanie zwolniony — tym zajmie się garbage collector.

Finalizator (ze znakiem !) wykonuje się w momencie, w którym garbage collector rzeczywiście zniszczyłby obiekt, ale żeby było śmiesznie, wykonanie się finalizatora powoduje dalsze opóźnienie zniszczenia obiektu do następnego przebiegu garbage collectora. [upraszczam: w rzeczywistości jest jeszcze gorzej] Ryzykujemy tym, że obiekt zostanie uznany za „długotrwały”, co może przesunąć zwolnienie pamięci aż do momentu zamknięcia programu…
Dlatego lepiej GC zostawić w spokoju, niech robi swoje.

Poza tym (i dotyczy to też natywnych aplikacji) zwolnienie jakiegoś obiektu w programie nie oznacza od razu, że pamięć zostanie zwrócona do systemu — runtime aplikacji (czy to .Net Framework, czy biblioteka standardowa C) może uznać, że lepiej przetrzymać zwolniony obszar dla przyszłych alokacji.

1
Tworzę sobie dynamicznie zakładkę (i kilka kontrolek na niej) i w pewnej funkcji ją usuwam ale nie wiem czy dobrze robię bo spoglądając w menadżera zadań pamięci nie ubywa (przed utworzeniem zakładki było 12 600KB, po utworzeniu 13 800KB, po skasowaniu również 13 800KB).

Nie przejmuj się tym. .NET rezerwuje sobie więcej pamięci niż chwilowo potrzebuje żeby móc ją szybko alokować w razie potrzeby, a jeśli system narzeka że ma mało pamięci, zwalnia nadmiar.

0

Po tym co przeczytałem dochodzę to wniosku, że do mojego kodu nic dodawać nie muszę. Znaczy dodałem jeszcze

System::GC::Collect();

i trochę zasobów zwalnia ale nie wszystko jednak. Mam tylko nadziej, że po dłuższym używaniu GC zadziała i mały programik nie będzie zajmował GB na dysku :D

0

to wywal i to. jak chcesz mieć minimalne zużycie pamięci, to nie .Net.
ja myślę, że pamięci masz wielokrotnie więcej niż ten jeden megabajt na którym ci tak zależy.

0

Wołanie GC::Collect na wyrost tylko zwiększy użycie procesora.

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