Form kapatırken memory den atma

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
aliplane
Üye
Mesajlar: 30
Kayıt: 06 Eki 2008 03:32

Form kapatırken memory den atma

Mesaj gönderen aliplane »

Aşağıdaki şekilde create ettiğim formu memoryden atacak şekilde nasıl close edebilirim?
Mdi application kullanmıyorum.
action:=cafree; komutu ile kapattığımda access violation exception alıyorum.

Kod: Tümünü seç

var
childMK:TMKFrm;
begin 
childMK:=TMKFrm.Create(Application);
childMK.Show;
Kullanıcı avatarı
SimaWB
Üye
Mesajlar: 1316
Kayıt: 07 May 2009 10:42
Konum: İstanbul
İletişim:

Re: Form kapatırken memory den atma

Mesaj gönderen SimaWB »

Create içerisinde parametre olarak (Owner parametresi) Application kullandığınız için sizin Free yapmanıza gerek yok. Zaten formunuzun sahibi uygulamanız olduğu için, uygulamayı kapattığınızda hafızada form için ayrılan kısım da serbest kalacaktır.
There's no place like 127.0.0.1
aliplane
Üye
Mesajlar: 30
Kayıt: 06 Eki 2008 03:32

Re: Form kapatırken memory den atma

Mesaj gönderen aliplane »

Evet,ancak kullanıcı uygulamayı kullandıkça bellekteki size artmazmı?
Kullanıcı avatarı
SimaWB
Üye
Mesajlar: 1316
Kayıt: 07 May 2009 10:42
Konum: İstanbul
İletişim:

Re: Form kapatırken memory den atma

Mesaj gönderen SimaWB »

Şimdi aklıma geldi; asıl sorunuzun cevabı olarak; childMK'nın FormClose'unda

Kod: Tümünü seç

Action := caFree; 
childMK := nil;
dener misiniz? Sorunsuz çalışması gerekir diye düşünüyorum.
En son SimaWB tarafından 12 Eki 2012 10:17 tarihinde düzenlendi, toplamda 2 kere düzenlendi.
There's no place like 127.0.0.1
aliplane
Üye
Mesajlar: 30
Kayıt: 06 Eki 2008 03:32

Re: Form kapatırken memory den atma

Mesaj gönderen aliplane »

childMK := nil; kullanamam çünkü bu komutu openerda yazabilirim.
childMK değişkenini de zaten göremem ki.
showmodal bir form olsaydı formun show edildikten sonra finaly bloğunda yazabilirdim.
Kullanıcı avatarı
unicorn64
Üye
Mesajlar: 919
Kayıt: 04 Nis 2006 08:56
Konum: yine yeniden Ankara ^_^

Re: Form kapatırken memory den atma

Mesaj gönderen unicorn64 »

childMK := nil;
yerine
self:=nil;
olarak kullanabilirsiniz
bazen yükselmek için önce dibi görmek gerekir...

forumda soru sormadan önce bakılmalı bence
daha fazlası için...

yürümeyi öğrenmeden koşmaya çalışanlar için, tökezleyip düşmek kaçınılmazdır...

Resim
Kullanıcı avatarı
Lost Soul
Üye
Mesajlar: 1064
Kayıt: 01 Nis 2007 02:55
Konum: mekan ANKARA toprak ELAZIĞ
İletişim:

Re: Form kapatırken memory den atma

Mesaj gönderen Lost Soul »

yanlış hatırlamıyorsam self := nil yemiyordu onclosede
Kullanıcı avatarı
SimaWB
Üye
Mesajlar: 1316
Kayıt: 07 May 2009 10:42
Konum: İstanbul
İletişim:

Re: Form kapatırken memory den atma

Mesaj gönderen SimaWB »

aliplane yazdı:childMK := nil; kullanamam çünkü bu komutu openerda yazabilirim.
childMK değişkenini de zaten göremem ki.
showmodal bir form olsaydı formun show edildikten sonra finaly bloğunda yazabilirdim.
"opener"dan kasıt nedir anlayamadım?

Tekrar özetlemek gerekirse; ana formda:

Kod: Tümünü seç

procedure TForm1.Button5Click(Sender: TObject);
var
  childMK: TMKFrm;
begin 
  childMK := TMKFrm.Create(Application);
  childMK.Show;
end;
ve TMKFrm'un tanımlı olduğu Unit'te:

Kod: Tümünü seç

procedure TMKFrm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  Self:= nil;
end;
yaptığınız halde hata alıyorsanız bence problem başka bir yerdedir.
There's no place like 127.0.0.1
Kullanıcı avatarı
SimaWB
Üye
Mesajlar: 1316
Kayıt: 07 May 2009 10:42
Konum: İstanbul
İletişim:

Re: Form kapatırken memory den atma

Mesaj gönderen SimaWB »

Lost Soul yazdı:yanlış hatırlamıyorsam self := nil yemiyordu onclosede
OnClose'da Self := nil; çalışır ve hatta ikinci formu global tanımladıysanız ve birden çok kez Create kullandıysanız Self := nil'i kullanmalısınız.
Detaylı bilgi için buraya bakılabilir.

Not: bir önceki verdiğim cevapta ikinci form locak tanımlandığı için buna gerek olmayabilir ama yine de emin olmak için memory leak kontrolü yapılabilir.
There's no place like 127.0.0.1
Kullanıcı avatarı
Lost Soul
Üye
Mesajlar: 1064
Kayıt: 01 Nis 2007 02:55
Konum: mekan ANKARA toprak ELAZIĞ
İletişim:

Re: Form kapatırken memory den atma

Mesaj gönderen Lost Soul »

SimaWB yazdı:
Lost Soul yazdı:yanlış hatırlamıyorsam self := nil yemiyordu onclosede
OnClose'da Self := nil; çalışır ve hatta ikinci formu global tanımladıysanız ve birden çok kez Create kullandıysanız Self := nil'i kullanmalısınız.
Detaylı bilgi için buraya bakılabilir.

Not: bir önceki verdiğim cevapta ikinci form locak tanımlandığı için buna gerek olmayabilir ama yine de emin olmak için memory leak kontrolü yapılabilir.

Bu konuyla ilgili bir başlık zamanında açılmıştı. Mesele de assigned ile ilgili bişeydi ve yanlış hatırlamıyorsam soruyu soran da bendim :)

Bir proje oluşturdum proje içinde Form1 ve Form2 var form1 de bir button var ve form2nin onclosesinde işe şu ibare var

Kod: Tümünü seç

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  Self := nil;
end;
form2 button clickte ise aşağıdaki kod var.

Kod: Tümünü seç

procedure TForm1.Button1Click(Sender: TObject);
var
  f : TForm2;
begin
  f := nil;
  ShowMessage(VarToStr(Assigned(f)));
  f := TForm2.Create(Application);
  ShowMessage(VarToStr(Assigned(f)));
  f.ShowModal;
  ShowMessage(VarToStr(Assigned(f)));
  f := nil;
  ShowMessage(VarToStr(Assigned(f)));



end;
Sonuç

Kod: Tümünü seç

False
True
True <- Buraya dikkat
False
eğer self := nil işini görüyor olsaydı 3. showmessage de false olmalıydı.
yani; evet action cafree formu free edip memory leakin önüne geçiyor.
fakat self := nil bir anlam ifade etmiyor.

şimdi vaktim kısıtlı geniş bi zamanda bu assigned meselesi ile ilgili bahsettiğim başığı da bulursam koyarım buraya inşallah.
Kullanıcı avatarı
Lost Soul
Üye
Mesajlar: 1064
Kayıt: 01 Nis 2007 02:55
Konum: mekan ANKARA toprak ELAZIĞ
İletişim:

Re: Form kapatırken memory den atma

Mesaj gönderen Lost Soul »

Başlığı buldum İleti başlığı: Re: nil ya da Assigned'den farklı bi komut mu çıktı :)

Bu da Self := nil meselesi ile ilgili olan kısmı

Bu arada dipnot: OnDestroyda self := nil yazmak da birşeye yaramıyor.
Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Re: Form kapatırken memory den atma

Mesaj gönderen vkamadan »

@Lost Soul kesinlikle haklı ,
self := nil ile form yokedilirken forma nil atandıktan sonta Assigned = TRUE döndürmeye devam ediyor.
Volkan KAMADAN
www.polisoft.com.tr
Kullanıcı avatarı
unicorn64
Üye
Mesajlar: 919
Kayıt: 04 Nis 2006 08:56
Konum: yine yeniden Ankara ^_^

Re: Form kapatırken memory den atma

Mesaj gönderen unicorn64 »

sanırım free edilmediği sürece bu durum söz konusu...
şuan deneme şansım yok ama on close da self.free; dense nasıl olur,
bir de aklıma şu geldi, formu create ederken parametre olarak nil geçip denermisiniz...
bazen yükselmek için önce dibi görmek gerekir...

forumda soru sormadan önce bakılmalı bence
daha fazlası için...

yürümeyi öğrenmeden koşmaya çalışanlar için, tökezleyip düşmek kaçınılmazdır...

Resim
Kullanıcı avatarı
SimaWB
Üye
Mesajlar: 1316
Kayıt: 07 May 2009 10:42
Konum: İstanbul
İletişim:

Re: Form kapatırken memory den atma

Mesaj gönderen SimaWB »

Lost Soul yazdı:
SimaWB yazdı:
Lost Soul yazdı:yanlış hatırlamıyorsam self := nil yemiyordu onclosede
OnClose'da Self := nil; çalışır ve hatta ikinci formu global tanımladıysanız ve birden çok kez Create kullandıysanız Self := nil'i kullanmalısınız.
Detaylı bilgi için buraya bakılabilir.

Not: bir önceki verdiğim cevapta ikinci form locak tanımlandığı için buna gerek olmayabilir ama yine de emin olmak için memory leak kontrolü yapılabilir.

Bu konuyla ilgili bir başlık zamanında açılmıştı. Mesele de assigned ile ilgili bişeydi ve yanlış hatırlamıyorsam soruyu soran da bendim :)

Bir proje oluşturdum proje içinde Form1 ve Form2 var form1 de bir button var ve form2nin onclosesinde işe şu ibare var

Kod: Tümünü seç

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  Self := nil;
end;
form2 button clickte ise aşağıdaki kod var.

Kod: Tümünü seç

procedure TForm1.Button1Click(Sender: TObject);
var
  f : TForm2;
begin
  f := nil;
  ShowMessage(VarToStr(Assigned(f)));
  f := TForm2.Create(Application);
  ShowMessage(VarToStr(Assigned(f)));
  f.ShowModal;
  ShowMessage(VarToStr(Assigned(f)));
  f := nil;
  ShowMessage(VarToStr(Assigned(f)));



end;
Sonuç

Kod: Tümünü seç

False
True
True <- Buraya dikkat
False
eğer self := nil işini görüyor olsaydı 3. showmessage de false olmalıydı.
yani; evet action cafree formu free edip memory leakin önüne geçiyor.
fakat self := nil bir anlam ifade etmiyor.

şimdi vaktim kısıtlı geniş bi zamanda bu assigned meselesi ile ilgili bahsettiğim başığı da bulursam koyarım buraya inşallah.
Benim de şuanda vaktim yok, müsait olduğumda kontrol edeceğim ama sizin oluşturduğunuz 2. form lokal tanımlanmış. Bense cevabımda özellikle belirtmiştim: "ikinci formu global tanımladıysanız" şeklinde.
Hafta içi vakit bulabilirsem ben de bir iki deneme yapıp burada paylaşırım inşallah.
There's no place like 127.0.0.1
Kullanıcı avatarı
Lost Soul
Üye
Mesajlar: 1064
Kayıt: 01 Nis 2007 02:55
Konum: mekan ANKARA toprak ELAZIĞ
İletişim:

Re: Form kapatırken memory den atma

Mesaj gönderen Lost Soul »

Globalda sorun yok zaten değişken ismi global olduğu için onclose veya ondestroyda self yerine global değişkenin (yani form2) ismini kullanarak nil ataması yapıldığında Assigned False dönüyor ancak self := nil dendiğinde global değişken için de olsa Assigned True dönüyor.

Yani aşağıdaki metod için

Kod: Tümünü seç


implementation
uses unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2 := nil;
  ShowMessage(VarToStr(Assigned(Form2)));
  Form2 := TForm2.Create(Application);
  ShowMessage(VarToStr(Assigned(Form2)));
  Form2.ShowModal;
  ShowMessage(VarToStr(Assigned(Form2)));
  Form2 := nil;
  ShowMessage(VarToStr(Assigned(Form2)));


end;

Kod: Tümünü seç

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  Form2 := Nil;//-<-----------
end;
dendiğinde sonuç

Kod: Tümünü seç

False
True
False<- Buraya dikkat
False
iken aşağıdaki kullanım için global değişken bile olsa

Kod: Tümünü seç

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  Self := nil; //-<-----------
end;

Kod: Tümünü seç

False
True
True<- Buraya dikkat
False
oluyor.



Şimdi memory leak için bu önemli mi? Hayır!
Zira form zaten bellekten atılmış oluyor. Sadece forma atanan referans değer nil olarak değişmiyor. Yani bellek alanı iade edilirken adres değeri sfırlanmıyor. Bu nedenle assigned metodu yemiyor. Fakat değişkenin üyelerine ya da metodlarrına erişmeye çalıştığınızda destoy edildiği için A.V. hatası alırsınız. Yani çok da önemli değil.
Cevapla