Pamięć - zwalnianie i wycieki

Odpowiedz Nowy wątek
jackoneill
2006-09-26 09:21
jackoneill
0

Witam
Mam taki problem:
Tłumaczę właśnie część kodu z VB do delphi (kilka class) i w miare wszystko się udaje ale chciałbym sprawdzić zwalnianie pamięci.
Jest to temat który bardzo słabo znam (w literaturze mi dostepniej tez jest lakonicznie - że trzeba itp).

Z tego co zrozumiałem po uzyciu .create muszę potem użyć .free , natomiast używająć SetLenght(xxx,10) trzeba użyć finalize.

Słyszałem że są jakiej programiki do badania wycieków pamięci.

Dla chcących mi pomóc dokładniej opisuję sytuacje:

  • 20 class (każda w osobnym unicie) ,
  • średnio po 40 procedur, funkcji i property w każdej klasie.

(przepatrzyłem archiwum i nic dokładnie nie znalazłem o dokładnej mozliwości analizowania pamieci)

Pozostało 580 znaków

2006-09-26 14:12

Rejestracja: 16 lat temu

Ostatnio: 7 lat temu

0

jest kilka zasad, które trzeba przestrzegać

  1. należy zwolnić wszystko, co sam tworzysz, czyli jak robisz Create to należy potem zrobić Free (zamiast Free lepiej zrobić FreeAndNil(obiekt))
  2. jeśli gdzieś używasz tablic dynamicznych to jeśli są już nie potrzebne należy je zwolnić przez SetLength(tablica, 0)
    do testowania jest pod Delphi DUnit albo MemProof a tu masz opisane wycieki pamięci i jak im zapobiegać w różnych wersjach Delphi i BCB

- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

jackoneill
2006-09-26 20:02
jackoneill
0

Wielkie dzięki - super odp - takiej odpowiedzi chciałem i tego szukałem - jak bedziesz około Olsztyna masz krate browara. [browar]

Pozostało 580 znaków

2006-09-26 22:30

Rejestracja: 14 lat temu

Ostatnio: 10 lat temu

0
Misiekd napisał(a)

jest kilka zasad, które trzeba przestrzegać

  1. jeśli gdzieś używasz tablic dynamicznych to jeśli są już nie potrzebne należy je zwolnić przez SetLength(tablica, 0)

... lub przez tablica := nil;

Jeśli tablica dynamiczna jest zmienną lokalną w procedurze/funkcji, to nie trzeba jej zwalniać - zajmie się tym delphiowy menedżer pamięci - podobnie jak nie trzeba "czyścić" lokalnych zmiennych typu String, OleVariant lub typów interfejsowych (IUnknown i pochodne). Tego typu zmiennych lokalnych nie trzeba również inicjować przed użyciem - są automatycznie inicjowane na wartość "pustą" przez kod wygenerowany przez kompilator.


M.O.R.R.I.S.: Mechanical Obedient Replicant Responsible for Infiltration and Sabotage
morris#rarlab*com

Pozostało 580 znaków

2008-08-02 02:26

Rejestracja: 13 lat temu

Ostatnio: 3 lata temu

Lokalizacja: Poznań

0

tablice nalezy zwalniac przez
Finalize()
wtedy gdy nie sa deklarowane jako lokalne oraz gdy zajmowane przez nie zasoby sa kluczowe dla aplikacji.


Tomasz Andrzejewski
Delphi (XE3-XE7) framework engineer @ InterLan
MCP: Microsoft SQL Server 2008, Implementation and Maintenance

Pozostało 580 znaków

Specjalisci_domowego
2008-08-02 13:10
Specjalisci_domowego
0

Tablice dynamiczne trzeba zwalniać? Specjaliści, a stringa też zwalniacie? :D

Słyszeliście o czymś takim jak licznik odwołań? :P

Pozostało 580 znaków

ŁF
2008-08-02 17:00
ŁF
Moderator

Rejestracja: 17 lat temu

Ostatnio: 2 dni temu

0

geniuszu, oczywiście sam nic nie zwalniasz w dynamicznej tablicy obiektów?
chyba nie wiesz co to licznik odwołań, nie ma on do rzeczy nic przy ręcznie tworzonych obiektach, jeśli obiektu nigdzie nie niszczysz, to co mu pomoże licznik, co?
a może język programowania pomyliłeś? java? c#?


Pozostało 580 znaków

TBSO
2008-08-02 22:05
TBSO
0

ŁF - on ma rację. tablicy dynamicznej jako takiej nie trzeba zwalniać. Obiekty, które są w niej przechowywane, o ile nie są prymitywami - tak, ale tego z kolei nie załatwi się instrukcjami podanymi przez Miśka i kolegów. Wyobraź sobie, że do tablicy dynamicznej pakujesz wskazania do komponentów utworzonych w taki sposób:

Tab[i] := TJakisKomponent.Create(Application);

Niech Cię ręka boska broni zwalniać tu COKOLWIEK - o zwolnienie obiektów zatroszczy się Application, a tablica zostanie usunięta samoczynnie.

Proponuję potestować trochę program pod D2006 wzwyż z włączoną opcją raportowania błędów lub - w przypadku niższych wersji Delphi - z podłączonym FastMM. Wnioski są jednoznaczne - tablic dynamicznych NIE TRZEBA zwalniać.

Pozostało 580 znaków

ŁF
2008-08-02 22:56
ŁF
Moderator

Rejestracja: 17 lat temu

Ostatnio: 2 dni temu

0
TBSO napisał(a)

Wyobraź sobie, że do tablicy dynamicznej pakujesz wskazania do komponentów utworzonych w taki sposób:

Tab[i] := TJakisKomponent.Create(Application);

Niech Cię ręka boska broni zwalniać tu COKOLWIEK - o zwolnienie obiektów zatroszczy się Application, a tablica zostanie usunięta samoczynnie.

przykład banalny:

var
  a : array of TObject;
...

procedure TForm1.Button1Click(Sender: TObject);
var
  i : integer;
begin
  setlength(a,100000);
  for i := 0 to length(a)-1 do a[i] := TObject.Create();
  a := nil;
end;

poklikaj w buttona i zobacz, czy pamięć na pewno się zwalnia. co do stringów i innych typów nie będących obiektami, w tym tablic dynamicznych - masz rację, Delphi zwalnia pamięć za mnie.


Pozostało 580 znaków

TBSO
2008-08-02 23:18
TBSO
0

Przeoczyłeś że tam było ".Create(Application)"?

Jak napisałem - zwalnianie obiektów przypisanych do elementów tablicy to jedna rzecz, to trzeba rozpatrywać indywidualnie - obiekty posiadające właściciela są zwalniane przez niego. Natomiast sama tablica dynamiczna zwalniania nie wymaga, no ale tutaj się już chyba zgodziliśmy :)

Pozostało 580 znaków

ŁF
2008-08-03 13:57
ŁF
Moderator

Rejestracja: 17 lat temu

Ostatnio: 2 dni temu

0

masz rację, ale z jednym dużym ALE. Application jest globalne dla całego programu, jeśli będzie ownerem, to spowoduje, że pamięć zostanie zwolniona dopiero przy zakończeniu aplikacji. w zasadzie to samo tyczy się wszystkich formatek i ich elementów, tak więc jest to metoda na zrobienie wycieków pamięci. co prawda będą posprzątane przy zamykaniu aplikacji, ale kogo to wtedy obchodzi?
tak więc dalej będę obstawać przy założeniu, że KAŻDY obiekt utworzony ręcznie POWINIEN być zwolniony ręcznie, a już zawsze, gdy kod pisze programista-amator, który nie panuje nad tym, kiedy jaki owner jest niszczony.

poza tym - założę się, że nawet nie sprawdziłeś w praktyce tego, co pisałeś. a ja to zrobiłem. zmień w moim kodzie TObject na TForm1, poklikaj na buttona i sam sprawdź, co się dzieje z pamięcią i uchwytami.


Pozostało 580 znaków

Odpowiedz

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