Thread ve memory kullanımı hakkında

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Kullanıcı avatarı
lazio
Moderator
Mesajlar: 1527
Kayıt: 11 Tem 2003 04:55
Konum: İstanbul

Mesaj gönderen lazio »

Konunun tamamını okumadım ama Kullandığın thread i manuel olarak Destroy ediyormusun?
DeveloperToolKit

..::|YeşilMavi|::..
Kullanıcı avatarı
hdayi
Kıdemli Üye
Mesajlar: 1284
Kayıt: 29 Oca 2004 01:53
Konum: Erciyes'in eteklerinden.

Mesaj gönderen hdayi »

Manuel? :roll: Destroy? :roll:

Hayır. Thread çalıştıktan sonra kendi kendini yok etmiyor mu? Yani ben öyle biliyorum? Yanlış mı? :oops: :oops: :oops:
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 »

FreeOnTerminate = True ise Execute'tan çıktığında thread otomatik free olur.
Kullanıcı avatarı
hdayi
Kıdemli Üye
Mesajlar: 1284
Kayıt: 29 Oca 2004 01:53
Konum: Erciyes'in eteklerinden.

Mesaj gönderen hdayi »

Sanırım çözüldü. Biraz daha test edip emin olmam lazım.
Burada şöyle bir şey buldum
There might be a problem with many connections remaining open (particularly if the server responds with "Keep-Alive"). You might want to do HTTP.Disconnect somewhere.
Kodu şöyle değiştirdim:

Kod: Tümünü seç

                if httpclient.Connected then
                    httpclient.Disconnect;
                FreeAndNil(httpclient);
Oldu gibi, bekleyelim ve görelim zaman içinde artacak mı memory kullanımı.

Teşekkürler...
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 »

İlginç. Free de her ahval ve şeraitte zaten Disconnect etmesi lazım.
Kullanıcı avatarı
hdayi
Kıdemli Üye
Mesajlar: 1284
Kayıt: 29 Oca 2004 01:53
Konum: Erciyes'in eteklerinden.

Mesaj gönderen hdayi »

Aslında ben de öyle düşşündüm. Olmayan bir şeyin bağlı kalması mümkün mü, ama fazla kod göz çıkarmaz diyelim. (Galiba yeni bir programcı deyimi icad ettim :lol: )
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 »

Problem olan en düşük kodu (ama çalışır bir şekilde) bizimle paylaşabilir misiniz? Problem büyük bir ihtimalle başka bir yerde.
Kullanıcı avatarı
hdayi
Kıdemli Üye
Mesajlar: 1284
Kayıt: 29 Oca 2004 01:53
Konum: Erciyes'in eteklerinden.

Mesaj gönderen hdayi »

Aslında daha önce yazmıştım kodu ama üstünde bir iki değişiklik oldu.

Thread'i çağırırken(arka arkaya 4 sefer ç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);

Thread ise şu şekilde

Kod: Tümünü seç

unit ImgDownload;

interface

uses
    Classes, idhttp, ExtCtrls, wininet, windows, strutils;

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

implementation

uses SysUtils;

{ thrImgDownload }

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

destructor thrImgDownload.Destroy;
begin
  
  inherited;
end;

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.Response.KeepAlive := False;
                httpclient.Get(thrurl, dosya);
            finally
                if httpclient.Connected then
                    httpclient.Disconnect;
                FreeAndNil(httpclient);
            end;
        finally
            dosya.Free;
        end;
        Synchronize(ImajYukle);
    except
        // Event handler konulabilir. Misal Synchronize(DoException);
    end;
end;

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

end.
Bu asıl programım değil, deneme için yaptığım bi şey.
Bir forma 4 adet timage koyduktan sonra bir buton'un onclick olayında thread'i çağırıyorum.
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 »

Epey geç oldu ama artık kusura bakma.

Baya bir test yaptım. Sonuçta try except end bloğunda hata yakaladım. Sebebi, threadler aynı dosyaya aynı anda yazmaya çalışıyor. Sen de try except end bloğunda hata yakalatmaya bakarsın.

Bunun dışında işlemi binlerce kez aralıksız tekrarlatıp bekledim. Hafıza başta baya bir gidiyor. Sonraki tekrarlarda tamamına yakını geri geliyor. Geri gelmeyen kısmı da kullanılan DLL ile ilgili diye düşünüyorum. Zira adamlar içinde neler yapıyor neler yapmıyor bilemiyoruz. (Tabi DLL program kapanırken free ediliyor.)

İyi çalışmalar.
Kullanıcı avatarı
undefined
Moderator
Mesajlar: 565
Kayıt: 06 Eki 2003 12:01
Konum: Bursa
İletişim:

Mesaj gönderen undefined »

Bence aynı dosyaya yazmıyorlar.
Sorun heapte oluşan fragmantasyon olabilir. Biraz araştırdım şu yazıyı buldum ama yazının tamamını okumadım. Süleyman demirel'in ünlü okuma tekniğiyle başına ortasını ve sonuna baktım :D

http://www.howtodothings.com/computers- ... elphi.html

Delphi 7 nin kullandığı memory managerı borland şu an terketti. Onun yerine FastMm yi kullanıyor. FastMM bir opensource proje.
FastMM is a lightning fast replacement memory manager for Borland Delphi Win32 applications that scales well in multi-threaded applications, is not prone to memory fragmentation, and supports shared memory without the use of external .DLL files
http://sourceforge.net/projects/fastmm

Bunu kullanmayı dene.

Kolay gelsin.
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

İyi ama her thread'e farklı dosya adı verilmiş. Ben de aynı dosyaya yazıldığını zannetmiyorum.

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);
Kullanıcı avatarı
hdayi
Kıdemli Üye
Mesajlar: 1284
Kayıt: 29 Oca 2004 01:53
Konum: Erciyes'in eteklerinden.

Mesaj gönderen hdayi »

Hakan Can yazdı:Epey geç oldu ama artık kusura bakma.
:) Estağfirullah, haddimize mi...
Hakan Can yazdı:Baya bir test yaptım. Sonuçta try except end bloğunda hata yakaladım. Sebebi, threadler aynı dosyaya aynı anda yazmaya çalışıyor. Sen de try except end bloğunda hata yakalatmaya bakarsın.
Verdiğim örenkte arka arkaya çalıştırınca evet aynı dosyaya yazıyor ama asıl programımda dosya adı şöyle:'

Kod: Tümünü seç

img'+FormatDateTime('hhmmsszzz', time) + 's.gif'
Yani milisaniyeye kadar saati de alarak dosyaya isim veriyorum. Aynı dosyaya yazmaya çalışıyor olması mümkün değil.
undefined yazdı:Delphi 7 nin kullandığı memory managerı borland şu an terketti. Onun yerine FastMm yi kullanıyor. FastMM bir opensource proje.
Bu FastMM'in içinden çıkamadım. Sadece readme.txt'si var onda da sadece dpr dosyasının uses kısmının başına FastMM unitini ekleyin diyor. Bir de BorlandMM.dll (adını yanlış hatırlıyor olabilirim) bunu değiştirin diyor. (aslında onu da demiyor da ben öyle bir mana çıkardım). Hiç bi doküman falan yok. Sitesinde hiç bi sayfa açılmıyor.
Ne oldu ki diyebilirsiniz acaip uzun bir hata verdi. Memory leak var dedi ama ne yapacağımı bilemedim.
Bişnev in ney çün hikâyet mîküned
Ez cüdâyîhâ şikâyet mîküned
Resim
Kullanıcı avatarı
undefined
Moderator
Mesajlar: 565
Kayıt: 06 Eki 2003 12:01
Konum: Bursa
İletişim:

Mesaj gönderen undefined »

Hocam, FastMM4 ü kullanmak için Zip'in kök dizininden çıkan FastMM4.pas, FastMM4options.inc, FastMM4messages.pas ı ya projenizin dizinine yada Delphi\lib dizinine atın. Ve projenizin dpr dosyasındaki uses'ın ilki FastMM4.pas olsun. Bu şekilde, yapmanız projede kullanmak için yeterli.

Eğer Delphi IDE'sinin bizzat FastMM4 ü kullanmasını istiyosanız. Delphi\Bin directorysindeki borlandMM.dll yi "\FastMM462\Replacement BorlndMM DLL\Precompiled\for Delphi IDE\Performance\BorlandMM.dll" ile değiştirin. Bu zorunlu değil...

Ayrıca Leak hatası veriyorsa:

Yanında gelen FAQ'dan alıntı :
Q: When my program shuts down FastMM reports that it has leaked memory. Is it possible that FastMM is wrong?
A: Unfortunately, no. If FastMM reports that a block has been leaked, then it means that a block was allocated but never freed - thus leaked. Use a utility like Memproof to pinpoint the source of the problem
Diyorki bu FastMM4 ün sorunu değil. Bir nesneyi yaratıyorsunuz ve free etmiyorsunuz FastMM4 de bunu sana rapor ediyor. FastMM4 bu konuda biraz sıkı anlayacağınız. Bence bu iyi bişey...

Kolay gelsin.
Kullanıcı avatarı
hdayi
Kıdemli Üye
Mesajlar: 1284
Kayıt: 29 Oca 2004 01:53
Konum: Erciyes'in eteklerinden.

Mesaj gönderen hdayi »

Bişey daha sorayım bununla ilgili. Bu dll dosyasını değiştirdiğim zaman, pas dosyasını yine eklemem gerekiyor mu? Yoksa sadece dll dosyasını değiştirmiş olmam yetiyor mu?
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 »

Bir dakika. BorlandMM sadece DLL ile olan string, dynamic char vs. alışverişinde kullanılır. Aksi takdirde kullanılmaz. Senin yazdığın bir DLL var ve onu thread ile mi kullanıyorsun?
Cevapla