XML Olusturmada OutOf Memory Hatası

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
ertank
Kıdemli Üye
Mesajlar: 1650
Kayıt: 12 Eyl 2015 12:45

Re: XML Olusturmada OutOf Memory Hatası

Mesaj gönderen ertank »

Merhaba,

Paylaştığınız kod hafıza kaçağı veya neden sürekli hafıza kullanımı artıyor sorunuzu cevaplamak için yeterli değil. Delphi içine yapıştırınca derlenebilir bir kod paylaşır iseniz sorunu bulmaya yardımcı olmak mümkün olabilir.

Bununla birlikte kullandığınız TStream türevinin ne olduğunu bilmeden;

Kod: Tümünü seç

Stream.CleanupInstance;
kullanım amacınızı anlayamadım. Sizin normalde

Kod: Tümünü seç

Stream.Clear();
şeklinde kullanmanız yeterli olacaktır.

Son olarak, olası hafıza kaçakları için Program->View Source menü seçeneği ile gelen yerde begin ifadesinden sonra ilk satıra

Kod: Tümünü seç

ReportMemoryLeaksOnShutdown := True;
ifadesini ekler iseniz uygulamayı kapattığınızda *eğer var ise* hafıza kaçağınız olduğunu size bildirecektir. Hafıza kaçağı yok ise bir mesaj gelmeyecektir.
ertank
Kıdemli Üye
Mesajlar: 1650
Kayıt: 12 Eyl 2015 12:45

Re: XML Olusturmada OutOf Memory Hatası

Mesaj gönderen ertank »

Merhaba,

Öncelikle bazılarında kati kural olarak, kural olmayanlarda da her bir programlama dili için genel kabul görmüş kod yazma formatı vardır. Paylaştığınız kodlarda blok kısımlarını ayırd etmek mümkün olmuyor. Bütün kod 1 numaralı kolondan başlıyor ve kodu okuması daha zor oluyor. begin..end arası, try..finally arası vb blok içinde kalan kodları minimum iki karakter boşluk vererek daha içeriden yazmanızda fayda var.

Ayrıca, kod örneklerinizi benim aşağıda yaptığım gibi code ve /code blokları içine yazmanız halinde okunması daha da kolay olan sabit genişlikli font ile ekranda gösterilecektir.

Paylaştığınız kod ile ilgili olarak. Neden yaklaşık 244MiB hafıza ayırdığınızı anlamadım. TFileStream kullanmanın amacı büyük boyutlu dosyalarda yüksek hafıza ihtiyacını ortadan kaldırmaya yöneliktir.

Bunun dışında nesneleri oluşturduktan sonra hafıza kaçağını engellemeye yönelik olarak try..finally bloğu içinde güvene almamışsınız. Arada yaptığınız işlemerlde bir hata oluşması durumunda bu hafıza kaçağına sebep olacaktır. Aynı konu StrAlloc() için de geçerli.

Sorunuzla ilgili emin olmamakla birlikte XML dosyasını UTF-8 olarak yazmak için bu şekilde bir kod yazdığınızı düşünüyorum. Kodunuzu daha pratik hale getirmek için Delphi 7 içindeki klasik string veri türünü ve ek bir prosedürü kullanarak yine istediğinizi daha basit şekilde elde etmeniz mümkün olabilir.

Kod: Tümünü seç

  procedure ConvertANSIFileToUTF8File(AInputFileName, AOutputFileName: string);
  var
    Strings: TStrings;
  begin
    Strings := TStringList.Create;
    try
      Strings.LoadFromFile(AInputFileName);
      Strings.Text := UTF8Encode(Strings.Text);
      Strings.SaveToFile(AOutputFileName);
    finally
      Strings.Free;
    end;
  end;

  procedure DatasetToXML(Dataset: TDataSet; FileName: string);
  var
    F: TextFile;
    bkmark: TBookmark;
    i: Integer;
  begin
    try
      AssignFile(F, Filename, CP_UTF8);
    except
      // Ne yapılması gerekiyor ise
      Exit;
    end;

    try
      ReWrite(F);
    except
      // Ne yapılması gerekiyor ise
      Exit;
    end;

    try
      WriteFileBegin(F, Dataset);

      with Dataset do
      begin
        DisableControls;
        bkmark := GetBookmark;
        First;

        { write a title row }
        WriteRowStart(F, True);
        for i := 0 to FieldCount - 1 do
          WriteData(F, nil, Fields.DisplayLabel);
        { write the end of row }
        WriteRowEnd(F, True);

        while (not EOF) do
        begin
          WriteRowStart(F, False);
          for i := 0 to FieldCount - 1 do
            WriteData(F, Fields, GetFieldStr(Fields));
          { write the end of row }
          WriteRowEnd(F, False);
          Next;
        end;
      end;
    finally
      WriteFileEnd(F);
      GotoBookmark(bkmark);
      EnableControls;
      CloseFile(F);
      ConvertANSIFileToUTF8File(Filename, Filename);
    end;
  end;
Mevcut kod olmadığı için yeniden düzenlenmesi gereken aşağıdaki prosedürleriniz için örnek kod hazırlayamadım
WriteFileBegin()
WriteRowStart()
WriteData()
WriteRowEnd()
WriteFileEnd()
ertank
Kıdemli Üye
Mesajlar: 1650
Kayıt: 12 Eyl 2015 12:45

Re: XML Olusturmada OutOf Memory Hatası

Mesaj gönderen ertank »

mert_37 yazdı: 09 Eki 2019 09:08 Cevap için teşekkür ederim...

Çok haklısınız Ertan bey Bu hafıza olayı 244 MB bireyre girmedim ama ben göremedim. SourceBuffer := StrAlloc(256000000); satırı 244 MB mi yapıyor. ?
Ben kısaca şöyle söylim. Bu örnek, derme çatma , kurcalaya kurcalaya biraz ezbere yaptığım bir çallışma.
ama uzun süre calıştı işimi de gördü.
Tam olarak 244,140625 MiB yapıyor.
mert_37 yazdı: 09 Eki 2019 09:08 Bu örneği bir yerde başka bir projede kullanmak istedim. Sorunda burada başladı.

Aslında biliyorum ya hafızayı arttıracam yada hafızada olup biteni tamamıyla silemem gerek.
Verdiğim komutlar işe yaramıyor. Bır şekile Out Of Memmory hatası veriyor ...
Hafızayı nasıl yükseltebilirim ? Atma olayından vazgeçtim.
Hafıza yükseltmenize gerek yok. Çok yüksek ihtimal ile kullandığınız kodun 244MiB hafıza ihtiyacı da yok. Size gönderdiğim örnek kodları inceler iseniz TFileStream yerine bu kod içindeki TextFile türünü kullanabilirsiniz.

Normalde her windows uygulamasının işletim sistemi tarafından bir maksimum hafıza kullanım limiti vardır. İçinde hata olan bir uygulama sistem kaynaklarının tamamını kullanıp sistemi kararsız hale getirmesini önlemek için bu limitler tanımlanmıştır. Windows 32bit uygulamalar için bu limit 2GB, Windows 64Bit uygulamalar için ise 16TiB limit vardır. Bu limitler bilgisayarda yüklü RAM miktarı bağımsızdır. Yani bilgisayarda 64BG ram dahi olsa 32Bit uygulama maksimum 2GB kısmını kullanabilir.

32Bit uygulamalar için 2GB limitini 4GB civarına çıkarmak için yöntemler mevcut. Ancak dediğim gibi, sizin uygulamanız için böyle bir ihtiyaç olacağına pek olasılık vermiyorum.
Cevapla