Thread ve memory kullanımı hakkında

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Kullanıcı avatarı
hdayi
Kıdemli Üye
Mesajlar: 1284
Kayıt: 29 Oca 2004 01:53
Konum: Erciyes'in eteklerinden.

Thread ve memory kullanımı hakkında

Mesaj gönderen hdayi »

Merhaba,
Bir thread kullanarak, 4 adet resim indirip 4 adet TImage nesnesinde gösteriyorum. Ancak bu threadleri her çalıştımdığımda prpogramın kullandığı memory artıyor. Yani thread çalışırken artıyor ancak bittiği zaman eski haline inmiyor. 4k kadar bazan 8k kadar daha fazla oluyor bu memory kullanımı. Birkaç thread'îm daha var, hepsinde de netten dosya indiriyor ve bazı işlemler yapıyorum. Birleşince çok acaip şeyler çıkıyor. 4-5 mb den başlayıp 10 mb'ye falan çıkıyor program.

Fikri olan? Yol gösterecek olan?

Thread'im şöyle:

Kod: Tümünü seç

unit ImgDownload;

interface

uses
    Classes, idhttp, ExtCtrls;

type
    thrImgDownload = class(TThread)
    private
    { Private declarations }
        thrurl, thrldosya: string;
        thrImg: Timage;
        IslemTamam: Boolean;
    protected
        procedure Execute; override;
        procedure ImajYukle;
    public
        constructor create(url, ldosya: string; img: Timage);
    end;

implementation

uses SysUtils;

{ thrImgDownload }

constructor thrImgDownload.create(url, ldosya: string; img: Timage);
begin
    FreeOnTerminate := True;
    thrurl := url;
    thrldosya := ldosya;
    thrImg := img;
    inherited create(True);
    Priority := tpLowest;
    resume;
end;

procedure thrImgDownload.Execute;
var
    Dosya: TFileStream;
    httpclient: Tidhttp;
begin
  { Place thread code here }
    try
        try
            dosya := TFileStream.create(thrldosya, fmCreate);
            httpclient := TIdHTTP.Create(nil);
            httpclient.ReadTimeout:=5000;
            httpclient.Get(thrurl, dosya);
            dosya.Free;
            Synchronize(ImajYukle);
        except
            Dosya.Free;
            if FileExists(thrldosya) then
                DeleteFile(thrldosya);
        end;
    finally
        httpclient.Free;
    end;
end;


procedure thrImgDownload.ImajYukle;
begin
    thrImg.Picture.LoadFromFile(thrldosya);
    DeleteFile(thrldosya);
end;

end.
Şöyle çağırıyorum:

Kod: Tümünü seç

thrImgDownload.create('http://www.meteor.gov.tr/2003/iller/set7/kayseris.aspx','d:\tmps.gif',Image1);
thrImgDownload.create('http://www.meteor.gov.tr/2003/iller/set7/kayseri1.aspx','d:\tmp1.gif',Image2);
thrImgDownload.create('http://www.meteor.gov.tr/2003/iller/set7/kayseri2.aspx','d:\tmp2.gif',Image3);
thrImgDownload.create('http://www.meteor.gov.tr/2003/iller/set7/kayseri3.aspx','d:\tmp3.gif',Image4);
Bişnev in ney çün hikâyet mîküned
Ez cüdâyîhâ şikâyet mîküned
Resim
Hakan Can
Üye
Mesajlar: 634
Kayıt: 04 Mar 2005 04:27
Konum: Ankara

Mesaj gönderen Hakan Can »

constructor thrImgDownload.create(url, ldosya: string; img: Timage);
in ilk satırına
inherited create(True);
yazıp diğer kodları sonra yazıp dener misin?
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Re: Thread ve memory kullanımı hakkında

Mesaj gönderen fduman »

İzninle kodu biraz düzenliyorum. Bana bir leak vamış gibi gelmedi. Windows'un bellek yönetimi biraz tuhaf. Aldığı belleği hemen geri vermeyebilir.

Kod: Tümünü seç

procedure thrImgDownload.Execute;
var
    Dosya: TFileStream;
    httpclient: Tidhttp;
begin
    try
       dosya := TFileStream.create(thrldosya, fmCreate);
       try
          httpclient := TIdHTTP.Create(nil);
          try
             httpclient.ReadTimeout:=5000;
             httpclient.Get(thrurl, dosya);
          finally
             httpclient.Free;
          end;
       finally
          dosya.Free;
       end;
       Synchronize(ImajYukle);
    except
        // Event handler konulabilir. Misal Synchronize(DoException);
    end;
end;
Kullanıcı avatarı
hdayi
Kıdemli Üye
Mesajlar: 1284
Kayıt: 29 Oca 2004 01:53
Konum: Erciyes'in eteklerinden.

Re: Thread ve memory kullanımı hakkında

Mesaj gönderen hdayi »

coderlord yazdı:İzninle kodu biraz düzenliyorum.
Estağfirullah @coderlord.

@Hakan Can ve @coderlord'un dediklerini denedim. Her ikisinde de bazen 4k bazense 8k gibi bir artış oluyor.
Aceba TIdHttp kullanıyorum ondan mıdır? Onun bir bug'ı mıdır? Ya da jedi yüklü, o mu bişeyi bozdu gibi ihtimaller geliyor aklıma. Mümkün müdür? Yoksa saçmalıyor muyum?
Bişnev in ney çün hikâyet mîküned
Ez cüdâyîhâ şikâyet mîküned
Resim
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

@hdayi şimdi farkettim. :D

Tabii ki artış olacak. Gayet normal. Image'lerin içine grafik atıyorsun. Herbiri tabii ki bellekte yer kaplayacaklar. Normal bir durum bu.
Kullanıcı avatarı
hdayi
Kıdemli Üye
Mesajlar: 1284
Kayıt: 29 Oca 2004 01:53
Konum: Erciyes'in eteklerinden.

Mesaj gönderen hdayi »

ilkinde tamam ama, diğer çalıştırdıklarımda zaten var olan bir nesneyi replace etmiyor mu? yoksa eski imageler hafızada mı kalıyor?
Bişnev in ney çün hikâyet mîküned
Ez cüdâyîhâ şikâyet mîküned
Resim
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

Hmm. 2 ve sonraki çalıştırmalarında kaydadeğer bir yükselme olmamalı haklısın.

Pek tahmin etmiyorum ama image lerde leak olabilir düşüncesiyle. Image içeriğini clear etmeyi denesene.
Kullanıcı avatarı
hdayi
Kıdemli Üye
Mesajlar: 1284
Kayıt: 29 Oca 2004 01:53
Konum: Erciyes'in eteklerinden.

Mesaj gönderen hdayi »

coderlord yazdı:Pek tahmin etmiyorum ama image lerde leak olabilir
düşüncesiyle. Image içeriğini clear etmeyi denesene.
Sizin mesajdan sonra aklıma geldi hemen denedim.

Kod: Tümünü seç

    Image1.Picture := nil;
Yine aynı problemi yaşadım. Daha da ilginci, thread'de Syncronize için kullandığım procedure'deki

Kod: Tümünü seç

    thrImg.Picture.LoadFromFile(thrldosya);
satırını kaldırdım. Yani bu durumda Thread verdiğim bir url'deki gif'i indirip silmiş oldu ve hala memory problemi devam ediyor. Sanırım benim thread kullanımı ile ilgili bir bilgi noksanım var.
:roll: :roll: :roll:
Bişnev in ney çün hikâyet mîküned
Ez cüdâyîhâ şikâyet mîküned
Resim
Kullanıcı avatarı
hdayi
Kıdemli Üye
Mesajlar: 1284
Kayıt: 29 Oca 2004 01:53
Konum: Erciyes'in eteklerinden.

Mesaj gönderen hdayi »

Mesajı yazdıktan sonra aklıma geldi ve denedim. Thread kullanımından kaynaklanmıyor sanırım.
Thread'i biraz değiştirdim. Sadece bir lokal dosya ve TIdHttp create edip sonra da yok eden bir Thread oldu. Bir problem göremedim o zaman. Memory hep sabir kaldı ne kadar çalıştırırsam çalıştırayım.
Fakat dosya download edince hemen artıyor memory kullanımı. Bu kesinlikle (demeye de dilim varmıyor aslında başka bişey çıkar diye) TIdHttp'den kaynaklanıyor.
Bişnev in ney çün hikâyet mîküned
Ez cüdâyîhâ şikâyet mîküned
Resim
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

Indy'nin hangi sürümünü kullanıyorsun?
Kullanıcı avatarı
hdayi
Kıdemli Üye
Mesajlar: 1284
Kayıt: 29 Oca 2004 01:53
Konum: Erciyes'in eteklerinden.

Mesaj gönderen hdayi »

:roll:
Sürüm mü?
Nasıl öğrenirim?
Delphi 7 içinde gelen standart indy, bi upgrade falan yapmadım.
Bu arada,

Kod: Tümünü seç

    with TDownloadURL.Create(nil) do
    try
        URL := thrUrl;
        FileName := thrldosya;
        ExecuteTarget(nil);
        Synchronize(ImajYukle);
    finally
        Free;
    end;
diye değiştirdim kodu. Memory kullandıkça artmıyor ama, bomboş program daha açar açmaz 2 mb artıverdi birden bire.
Bir de bu fonksiyonun beğenmediğim bir yanı var ya da ben bişeyi yanlış yapmıştım zamanında, ie'den sayfayı refresh etmezsem bu da etmiyor, sanki cahce'den okuyor dosyayı gibi.
Bişnev in ney çün hikâyet mîküned
Ez cüdâyîhâ şikâyet mîküned
Resim
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

DownloadURL Internet Explorer kullanır. Pek tavsiye etmiyorum.

Indy'yi bir sürüm yükseltip dener misin? sendeki 9 bilmem kaç sürümü. Bir 9 sürümü daha çıkmıştı.
Kullanıcı avatarı
hdayi
Kıdemli Üye
Mesajlar: 1284
Kayıt: 29 Oca 2004 01:53
Konum: Erciyes'in eteklerinden.

Mesaj gönderen hdayi »

10.1.5'i indirdim şimdi. Kurmaya çalışıyorum. inşallah bu sefer olur :)
Bişnev in ney çün hikâyet mîküned
Ez cüdâyîhâ şikâyet mîküned
Resim
Kullanıcı avatarı
hdayi
Kıdemli Üye
Mesajlar: 1284
Kayıt: 29 Oca 2004 01:53
Konum: Erciyes'in eteklerinden.

Mesaj gönderen hdayi »

Olmuyor olmuyor diye bi şarkı vardı. 3. bir download yöntemi bulmam lazım. :cry: :cry: :cry:
Bişnev in ney çün hikâyet mîküned
Ez cüdâyîhâ şikâyet mîküned
Resim
Kullanıcı avatarı
gkimirti
Admin
Mesajlar: 1956
Kayıt: 02 Eyl 2003 04:44
Konum: İstanbul

Mesaj gönderen gkimirti »

Birde bunu denesene

Kod: Tümünü seç

function GetNetDocument(url, fname: string): boolean;
type
  mtype = array[0..1023] of byte;
var
  fulltxt: string;
  nread: cardinal;
  etxt: mtype;
  mhhtreq: HINTERNET;
  mhtturl: HINTERNET;
  mfile: file of mtype;

begin
  result := false;
  DeleteUrlCacheEntry(pchar(url));
  try
    mhhtreq := InternetOpen('mdown', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
    try
      mhtturl := InternetOpenUrl(mhhtreq, pchar(url), nil, 0, 0, 0);
      fulltxt := url;
      ReplaceStr(fulltxt, '/', '\');

      if fname = '' then
        fulltxt := extractfilename(fulltxt)
      else
        fulltxt := fname;
      AssignFile(mfile, fulltxt);
      Rewrite(mfile);
      repeat
        FillChar(etxt, 1024, #0);
        InternetReadFile(mhtturl, @etxt, sizeof(etxt), nread);
        Write(mfile, etxt);
        Application.ProcessMessages;
      until nread = 0;
    finally
      InternetCloseHandle(mhtturl);
      closefile(mfile);
    end;
  finally
    InternetCloseHandle(mhhtreq);
    result := true;
  end;
end;
ÜŞENME,ERTELEME,VAZGEÇME
Cevapla