Memory leak

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Kullanıcı avatarı
muratmutlu
Üye
Mesajlar: 57
Kayıt: 02 Tem 2005 02:44
Konum: Antalya

Memory leak

Mesaj gönderen muratmutlu »

Merhaba. Benim sorunum form üzerinde olan ya da runtime da yarattığım nesnelerde memory leak oluşması. Geliştirdiğim program 30 saniyede bir internet üzerinden dosya indiren bir servis programı. Programda pdf, xml ve text dosyaları indiriyorum. Bir timer içinde çalışan bir kodum var. O kod ise istenilen dosyaları bir klasöre indiriyor. Kodlar aşağıdaki gibidir:

Timer1 içeriği:

Kod: Tümünü seç

  try
    DosyalarOkunuyor := True;
    DosyalariIndir;
  finally
    DosyalarOkunuyor := False;
  end;
DosyalariIndir:

Kod: Tümünü seç

procedure TAnaForm.DosyalariIndir;
begin
  try
    Timer1.Enabled := False;
    ....
    ....
    İndirme işlemleri 
    ....
    ....
  finally
    Timer1.Enabled := True;
  end;
end
Dosya indiren fonksiyon:

Kod: Tümünü seç

function TAnaForm.DosyaIndir(Adres: String; KaydedilecekDosyaAdi: String): Boolean;
begin
  Result := True;
  with TDownloadURL.Create(Application) do
  try
    try
      URL := Adres;
      FileName := KaydedilecekDosyaAdi;
      ExecuteTarget(nil) ;
    except
      on E: Exception do
      begin
        Result := False;
        Exit;
      end;
    end;
  finally
    Free;
  end;
end;
Farklı bir dosya indirme yöntemi:

Kod: Tümünü seç

function TAnaForm.DosyaAl(Adres: String): AnsiString;
begin
  try
    Result := HTTP1.Get(Adres);
  except on E: Exception do
    Result := '';
  end;
end;
Bir text dosyanın ilk iki satırını silmek için kullandığım kod :

Kod: Tümünü seç

  TempStringList := TStringList.Create;
  try
    TempStringList.LoadFromFile(KaydedilecekDosyaAdi);
    TempStringList.Delete(0); // İlk satır
    TempStringList.Delete(TempStringList.Count-1); // Son satır
    TempStringList.SaveToFile(KaydedilecekDosyaAdi);
  finally
    TempStringList.Free;
  end;
Sonuç olarak yukarıda bahsettiğim her iki dosya indirme ve StringList işlemlerinde memory leak oluşuyor. Örneğin 260 kb lık bir pdf dosyası indirince yaklaşık o seviyelerde bir memory artışı oluyor ama Free ya da destroy dememe rağmen o memory i geri vermiyor. Normalde bir iki kez yapılacak bir işlem olsaydı çok önemsemeyebilirdim ama bir service mantığıyla ve hiç kapanmadan çalışması gerektiği için sıkıntı yaratıyor. İnternette yaptığım araştırmalarda Indy 10 ile ilgili genel bir problem olduğu söyleniyor ama bu konu TStringList i free etmeme engel olamaz diye düşünüyorum. Bu konu da nasıl bir yol izleyebilirim acaba ?

XE4
Win 7 Ultimate 32 bit SP1
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Memory leak

Mesaj gönderen mrmarman »

Test ederken stringlist create kısmını kullanmayacak şekilde dener misiniz.

Yani boş boş dosya indirip dursun.

En azından sorunun indy mi stringlist mi ya da programdaki başka bir aracı ile kombine üçüncü bir durum mu anlamış olursunuz.
Resim
Resim ....Resim
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Re: Memory leak

Mesaj gönderen sabanakman »

Bir de ek olarak (sorun dosya indirmeyle alakalı ise), tekrar edecek şekilde test etmeyi denediniz mi? Mesela bir süre sonra aynı boyutlarda bir dosya daha indirilince bu boyut 2 katına mı çıkıyor yoksa aynı seviyelerde mi kalıyor? Eğer bellek kullanımında üste katlanır bir biçiminde bir artış olmuyorsa, problem olmaz sanırım.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
akdatilla
Üye
Mesajlar: 292
Kayıt: 02 Nis 2006 06:04
Konum: Antalya

Re: Memory leak

Mesaj gönderen akdatilla »

merhaba
kodları şu şekilde çevirir misin?

Kod: Tümünü seç

procedure TAnaForm.DosyalariIndir;
begin
  try
    Timer1.Enabled := False;
    ....
    ....
    İndirme işlemleri
    ....
    ....
  except ///**
  end;
    Timer1.Enabled := True;
end

Kod: Tümünü seç

function TAnaForm.DosyaIndir(Adres: String; KaydedilecekDosyaAdi: String): Boolean;
var
  durl:TDownloadURL;
begin
  Result := True;
  durl:=TDownloadURL.Create(Application);
    try
      durl.URL := Adres;
      durl.FileName := KaydedilecekDosyaAdi;
      durl.ExecuteTarget(nil) ;
    except
      on E: Exception do
      begin
        Result := False;
      end;
    end;
    durl.Free;
    durl:=nil;
end;

Kod: Tümünü seç

TempStringList := TStringList.Create;
  try
    TempStringList.LoadFromFile(KaydedilecekDosyaAdi);
  except
  end;

    if TempStringList.Count>1 then
    begin
           TempStringList.Delete(TempStringList.Count-1); // Son satır
           TempStringList.Delete(0); // İlk satır
           try
              TempStringList.SaveToFile(KaydedilecekDosyaAdi);
           except
           end;
   end;
  TempStringList.Free;
  TempStringList:=nil;
  end;
Bunların dışında bir de "HTTP1.Get(Adres);" komutunu verdikten sonra bir bekleme gereksininmi olduğunu sanıyorum (bir timer kullanarak komutun tamamlanmasının beklenmesi gerekebilir).
kolay gelsin, iyi çalışmalar.
Kullanıcı avatarı
muratmutlu
Üye
Mesajlar: 57
Kayıt: 02 Tem 2005 02:44
Konum: Antalya

Re: Memory leak

Mesaj gönderen muratmutlu »

Yoğunluktan dolayı biraz geç dönebildim. Bu arada kodlara yine bakma şansım oldu. Boş bir proje açıp bir timer koyup interval özelliğini 100 ms olarak ayarladım ve çok sık aralıklarla HTTP.Get metodu ile dosya indirmeye başladım. Uzun bir süre beklememe rağmen herhangi bir taşma olmadan program devam etti. Bir de gidip stringlist e o dosyayı ekleyip ilk ve son satırlarını sildikten sonra farklı bir isimle başka bir yere daha kaydettim ama yine hafızada bir sıkıntı olmadı. Aslında ilginç olan şöyle bir durum daha var; Sorun sadece HTTP ya da stringlist de değil. Program create ettiği hiç bir şeyi free (FreeAndNil, Destroy) edemiyor :D . (Programın bir çok yerine Application.ProcessMessages koydum)

Tüm bu işlemleri kendi yarattığım bir nesne içinde yapıyorum. Kodum biraz karmaşık ve uzun olduğu için buraya taşıma imkanım yok. Ben kodumu biraz daha inceleyip sorunu çözünce buraya yazmayı düşünüyorum. Bilmiyorum belki de project options daki bir ayardan kaynaklanıyor olabilir. Hepinize teşekkür ederim.

Kolay gelsin.
Cevapla