Skocz do zawartości

[Delphi] faktyczne zwalnianie pamięci przez FreeAndNil itp.


flash

Polecane posty

Witam.

 

Mam program w Delphi, typowe formy ... i staram się przerobić go aby zajmował mniej pamięci po uruchomieniu, zacząłem od wyrzucenia form i tworzenia ich w momencie gdy są potrzebne, np taka typowa forma About.. dodaje konstruktora i tworze ją przez:

 

  if frmAbout=nil then frmAbout:= TfrmAbout.Create(Application);
 frmAbout.ShowModal;
 FreeAndNil(frmAbout);

 

wszystko ok aż do momentu gdy uruchamiam WinXP managera procesów i:

- przed otworzeniem About program zajmuje 9829 KB;

- otwieram About 9887 KB;

- FreAndNil ... zostaje 9887 KB;

jak przywrócić zajętość do stanu poprzedniego... np. 9829 KB; ?

 

poszukam jeszcze na ten temat ale to "odkrycie" rozbroiło mnie totalnie. Z góry dzięki za podpowiedzi.

Link do komentarza
Udostępnij na innych stronach

Ogólnie Delphi nie korzysta z systemowego managera pamięci. Zamiast tego uzywa swojego wrappera dookoła tego systemowego, podejrzewam ze niewielkie zmiany pamieci nie sa uwalniane a raczej trzymane jako podreczny buffor. W efekcie wzrasta wydajnosc z jaka dziala program gdyz nie ma czestych wywolan do niskopoziomowego managera pamieci, tylko mozna uzywac cachowania na poziomie aplikacji. Jak oduczyc Delphi tego zachowania nie wiem, trzeba by sie przyjrzec API tego managera, ale nie do konca widze sens walki o te kilka kiliobajtow (moze poza czysto akademickim sensem...)

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

kompilator Delphi 2007, manager WinXP

 

hm... niby macie rację że dla kilku KB.. przy jak na razie względnie prymitywnej aplikacji,

ale na tym przykładzie chciałem rozgryźć mechanizm potrzebny do dynamicznej listy formularzy,

np. otwieram kilka formularzy array of TFormaDokument i fajnie jeśli zamykam formularze z końca listy bo wtedy

SetLength(array, Length(array)-1); załatwia chyba wszystko ale jak niszczę formularz w środku listy to na dobrą sprawę przyjmuje on wartość nil a praktycznie ciągle zajmuje pamięć,

a formularze nie są małe i mają swoje "pod okna/ pod formy" więc jest się chyba jest to raczej opłacalne bo w grę wchodzą już kilka jak nie kilkadziesiąt MB; zakładam że w przyszłości taki jeden formularz to 2-5MB (dane, grafika, vcl)

 

Zastanowiło mnie to bo teraz jeśli używam klas a Delphi to praktycznie większości same klasy to właściwie żeby

program zajmował mało pamięci to albo pisać w API albo ... no właśnie,

weźmy taką pierwsza z brzegu klasę TStringList ... załóżmy że przy starcie programu wczytuje jakiś tekst -> jakieś dane,

po przetworzeniu których ją niszczę (bo już jej nie bede używał) a ona mi wisi w pamięci?

Jeśli tak to jak się jej faktycznie pozbyć, zastępując array of string czy czymś innym,

bo jeśli array nie zostanie niszczone to zawsze mniej miejsca zajmuje takie SetLength( array, 0),

tyle że nie zawsze array wystarczy :)

 

przykład jest prymitywny ale chodzi o zasadę zwalniania pamięci, no i może prób optymalizacji "tam gdzie się to opłaci", czyli właściwie mowa tu o klasach niewizualnych i o wizualnych.

Link do komentarza
Udostępnij na innych stronach

Cóż z twojego postu wynika że masz bardzo duże braki w podstawach Delphi (bez obrazy). To co mówisz mija się mocno z prawdą, możliwe że masz doświadczenia z C++/C, gdzie to wygląda trochę inaczej. Ale po kolei.

1. W delphi tworząc tablicę obiektów (np form) tworzysz de facto tablice pointerów do tych obiektów. Tak więc rozmiar tablicy na 8 elementów to 8 * wielkość pointera bez znaczenia na co ten pointer wskazuje.

2. Jak już wspomniałem manager pamięci delphi ma swoje wytyczne jak ma zarządzać zasobami. Prawie na pewno duże (ciężkie) obiekty są zwalniane, małe i lekkie pewnie są trzymane na podorędziu.

3. Zwolnienie obiektu ze środka tablicy, nie zmienia rozmiaru tablicy (wstawia się tam nil), ale obiekt który był referowany w tej tablicy może być usunięty.

4. "Ciężar" obiektu jest zależny tylko od pól które są w nim zdefiniowane. Cały kod jest kompilowany i wczytany tylko raz. Tak więc stworzenie miliona obiektów które nie mają w ogóle pól waży tylko tyle co referencje do tych obiektów + struktury wymagane do zarządzania nimi. To czy będziesz używał WIN API nic tutaj nie zmieni.

5. zamiast męczyć się z ręcznym zarządzaniem długością listy sięgnij po TList, robi to za ciebie.

Przejmowanie się pamięcią zajmowaną przez kontenery na 10-40 obiektów to strata czasu na głupoty. Jeśli miałbyś tam 100k obiektów albo więcej to ok, można to przemyśleć. Ale wtedy zapewne inne struktury byś używał zapewne słowniki albo drzewa a nie tablice. Dopóki twój app nie zżera kilkuset mega nie marnuj czasu na analizy tego typu. Z czasem pisząc coraz bardziej skomplikowane appsy lepiej zrozumiesz zarządzanie pamięcią i będziesz wiedział co warto optymalizować a co jest nic nie dającym wysiłkiem.

 

Powodzonka :)

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

kiedyś toczyła się dyskusja na podobny temat więc pozwolę sobie przypomnieć http://forum.unit1.pl/topic/1047-delphiprzydzial-i-zwalnianie-pamieci-uzywajac-wskaznikow/page__view__findpost__p__7214

 

 

Toster co do punktu 5

zwróć uwagę że taka "zabawa" nawet z niewielką ilością obiektów może pomóc poznać te mechanizmy - chyba że się mylę, w Delphi nie programowałem nic od lat ;)

Link do komentarza
Udostępnij na innych stronach

Jest taki moment gdzie człowiek zauważa, że program nie zajmuje 1-2 moduły tylko kilka-kilkanaście, robi się "gotowce", które się podpina, baza się rozrasta ... stąd też pomysł żeby wcześniej włączyć "optymalne" i żeby gotowce miały jak najmniej defektów,

co do pointerów to gdzieś w zakamarkach pamięci było ale że wchodzi moda na "inteligentne" zarządzanie pamięcią przez kompilatory - jakoś nie wpadło mi nic na ten temat w oko i z stąd te braki;

ciężko mi się będzie przyzwyczaić że mimo że chce coś zrobić a kompilator mi mówi ze jest lepsze rozwiązanie ... no może jak zacznie czytać w myślach i programować z fal mózgowych :) ...

Chyba muszę prześledzić nowości bo rzadkie bywanie na forach i nie śledzenie nowosci ma swoje skutki uboczne.

 

Dziękuję za rozmowę i wyjaśnienia

Link do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...