Veri aktarımı-out of memory hatası

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Kullanıcı avatarı
bobasturk
Kıdemli Üye
Mesajlar: 1387
Kayıt: 20 May 2004 08:39
Konum: Düzce

Veri aktarımı-out of memory hatası

Mesaj gönderen bobasturk »

Merhama,

xp işletim sistemi
E8400 3,0 GHZ
4 GB RAM
Delphi7
Firebird 2,1 sürümü

Ustalar, sorunum eski programdan yeni programa verileri aktarma. Master tablo ve detay tablolarım var. Master tabloda yaklaşık 20 000 kayıtta verileri aktarımda önce out of memory hatasını yaşamıştım ama arayüzde bulunan gridlerin bağlantısını kesince işlemi tamamladım. sıra detay tablolara geldi,

detay tablomda toplam 70857 kayıt var. kullandığım aktarım kodu;

Kod: Tümünü seç

try

  Screen.Cursor := crHourGlass;

    dm.eskidelilibqry.First;
    dm.YenidelilIBDSet.DisableControls;

  while not dm.eskidelilibqry.Eof do
  begin
    jvprogressbar2.Position:=jvprogressbar2.Position+1;
    dm.YeniDelilIBDSet.insert;
    dm.YeniDelilIBDSet.FieldByName('OLYID').AsInteger:=dm.eskidelilibqry.fieldbyname('OLAYID').AsInteger;
    dm.YeniDelilIBDSet.FieldByName('ILKODU').AsInteger:=0;
    dm.YeniDelilIBDSet.FieldByName('ILCEKODU').AsInteger:=0;
    dm.YeniDelilIBDSet.FieldByName('YIL').asinteger:=dm.eskidelilibqry.fieldbyname('OLAYYILI').asinteger;
    dm.YeniDelilIBDSet.FieldByName('RAPORNO').AsInteger:=dm.eskidelilibqry.fieldbyname('RAPORNO').AsInteger;
    dm.YeniDelilIBDSet.FieldByName('EKRAPORNO').AsInteger:=dm.eskidelilibqry.fieldbyname('EKRAPORNO').AsInteger;
    dm.YeniDelilIBDSet.FieldByName('INCELEMETARIH').AsDateTime:=dm.eskidelilibqry.fieldbyname('INCTARIHI').AsDateTime;
    dm.YeniDelilIBDSet.FieldByName('BULGUNO').AsString:=dm.eskidelilibqry.fieldbyname('DELILNO').AsString;
    dm.YeniDelilIBDSet.FieldByName('BULGUNUNTANIMI').AsString:=dm.eskidelilibqry.fieldbyname('DELILTANIMI').AsString;
    dm.YeniDelilIBDSet.FieldByName('TESPITYERI').AsString:=dm.eskidelilibqry.fieldbyname('TESPITYERI').AsString;
    dm.YeniDelilIBDSet.FieldByName('PARMAKIZI').AsString:=dm.eskidelilibqry.fieldbyname('PARMAKIZI').AsString;
    dm.YeniDelilIBDSet.FieldByName('AVUCIZI').AsString:=dm.eskidelilibqry.fieldbyname('AVUCIZI').AsString;
    dm.YeniDelilIBDSet.FieldByName('AYAKIZI').AsString:=dm.eskidelilibqry.fieldbyname('AYAKIZI').AsString;
    dm.YeniDelilIBDSet.FieldByName('VUCUTIZI').AsString:=dm.eskidelilibqry.fieldbyname('VUCUTIZI').AsString;
    dm.YeniDelilIBDSet.FieldByName('BIYOMETRI').AsString:=dm.eskidelilibqry.fieldbyname('BIYOMETRI').AsString;
    dm.YeniDelilIBDSet.FieldByName('VIGLAB').AsString:=dm.eskidelilibqry.fieldbyname('VIGLAB').AsString;
    dm.YeniDelilIBDSet.FieldByName('BALISTIK').AsString:=dm.eskidelilibqry.fieldbyname('BALISTIK').AsString;
    dm.YeniDelilIBDSet.FieldByName('KIMYASAL').AsString:=dm.eskidelilibqry.fieldbyname('KIMYASAL').AsString;
    dm.YeniDelilIBDSet.FieldByName('BIYOLOJIK').AsString:=dm.eskidelilibqry.fieldbyname('BIYOLOJIK').AsString;
    dm.YeniDelilIBDSet.FieldByName('AYAKKABIIZI').AsString:=dm.eskidelilibqry.fieldbyname('AYAKKABIIZI').AsString;
    dm.YeniDelilIBDSet.FieldByName('ALETIZI').AsString:=dm.eskidelilibqry.fieldbyname('ALETIZI').AsString;
    dm.YeniDelilIBDSet.FieldByName('LASTIKIZI').AsString:=dm.eskidelilibqry.fieldbyname('LASTIKIZI').AsString;
    dm.YeniDelilIBDSet.FieldByName('DIGERIZBULGU').AsString:=dm.eskidelilibqry.fieldbyname('DIGERIZBULGU').AsString;
    dm.YeniDelilIBDSet.FieldByName('IZINCELEME').AsString:=dm.eskidelilibqry.fieldbyname('IZINCELEME').AsString;
    dm.YeniDelilIBDSet.FieldByName('BELGE').AsString:=dm.eskidelilibqry.fieldbyname('BELGE').AsString;
    dm.YeniDelilIBDSet.FieldByName('SESDATA').AsString:=dm.eskidelilibqry.fieldbyname('SESDATA').AsString;
    dm.YeniDelilIBDSet.FieldByName('PALINOLOJIK').AsString:=dm.eskidelilibqry.fieldbyname('PALINOLOJIK').AsString;
    dm.YeniDelilIBDSet.FieldByName('ENTOMOLOJIK').AsString:=dm.eskidelilibqry.fieldbyname('ENTOMOLOJIK').AsString;
    dm.YeniDelilIBDSet.FieldByName('LABIZVAR').AsString:=dm.eskidelilibqry.fieldbyname('LABIZVAR').AsString;
    dm.YeniDelilIBDSet.FieldByName('LABIZYOK').AsString:=dm.eskidelilibqry.fieldbyname('LABIZYOK').AsString;
    dm.YeniDelilIBDSet.FieldByName('LABSONUC').AsString:=dm.eskidelilibqry.fieldbyname('LABSONUC').AsString;

    dm.YeniDelilIBDSet.Post;
    dm.eskidelilibqry.Next;
  end;
  finally
    showmessage('Veri Aktarım İşlemi Tamamlandı');
    Screen.Cursor := crDefault;
    dm.YenidelilIBDSet.EnableControls;
  
  end;
bu şekilde ve yaklaşık 30-40 bin kayda geldiğinde out of memory hatası alıyorum. firebird bu kadarcık veride ve 4 gb ram de bu hataların olmaması gerekiyormuş gibi geliyor. kod veya algoritmada mı hatam var. yardımcı olulrsanız sevinirim. kolay gelsin
Şefkat-u Merhamette Güneş Gibi Ol.
Başkalarının Kusurunu Örtmekte Gece Gibi Ol.
Sehavet-u Cömertlikte Akarsu Gibi Ol.
Hiddet-u Asabiyette Ölü Gibi Ol.
Tevazu-u Mahviyette Toprak Gibi Ol.
Ya Olduğun Gibi Görün Ya Göründüğün Gibi Ol.

Resim
Kullanıcı avatarı
NewMember
Üye
Mesajlar: 990
Kayıt: 29 Haz 2005 06:57
Konum: Bursa

Re: Veri aktarımı-out of memory hatası

Mesaj gönderen NewMember »

Bu tür sorunlarla çok boğuşmuş (hatta aynısı) birisi olarak denemediğim yol kalmadı.Çözüm se şu.
Bu tür bir işlemi yapmaya IBX bileşenleri yeterli gelmiyor.FıbPlus ise banamısın demiyor.Aynı kayıt aynı kod IBX Out of memory veriyor FIBPlus ise bunu başarıyor.
Ayrıca FB de 2.1 den 2.5 a geçmeni tavsiye ederim.
Buda bir etken.
esrehmaan

Re: Veri aktarımı-out of memory hatası

Mesaj gönderen esrehmaan »

kodunuzada sorun yok ama aşırı boğuluyor arkadaşın dediği gibi.. belli bir süreden sonrada hafıza hatanız almanız normal. şöyle diyeyim 0,5 saniyede çalışan kod 1 saniyede tablodan çekilen veriye yetişemiyor belli süreden sonra böyle oluyor neredeyse. firebird 2,5.1 geçeseniz rahatlarsınız ve başka bişey daha IBExpert programı kullarak verilerini export edip geri alabilirsiniz. ve emin olun çok daha hızlı ve sorunsuz
Kullanıcı avatarı
bobasturk
Kıdemli Üye
Mesajlar: 1387
Kayıt: 20 May 2004 08:39
Konum: Düzce

Re: Veri aktarımı-out of memory hatası

Mesaj gönderen bobasturk »

merhaba,

cevaplarınız için teşekkür ederim. ibexpert zaten kullanıyorum. tablo alan adları ve yapıları birebir aynı olsa tamam ama verileri export veya scripte çektiğim zaman alan adı uyuşmazlığı sebebiyle kullanamadım. fibplus ve firebird 2.5 tavsiyesini deneyeceğim.

kolay gelsin hayırlı çalışmalar
Şefkat-u Merhamette Güneş Gibi Ol.
Başkalarının Kusurunu Örtmekte Gece Gibi Ol.
Sehavet-u Cömertlikte Akarsu Gibi Ol.
Hiddet-u Asabiyette Ölü Gibi Ol.
Tevazu-u Mahviyette Toprak Gibi Ol.
Ya Olduğun Gibi Görün Ya Göründüğün Gibi Ol.

Resim
esrehmaan

Re: Veri aktarımı-out of memory hatası

Mesaj gönderen esrehmaan »

alan adlarının uyuşmasına gerek yokki.. onun ayarıda var çok basit pmden msn yolalrsanız yardımcı olurum
Kullanıcı avatarı
bobasturk
Kıdemli Üye
Mesajlar: 1387
Kayıt: 20 May 2004 08:39
Konum: Düzce

Re: Veri aktarımı-out of memory hatası

Mesaj gönderen bobasturk »

merhaba,

esrehmaan çok teşekkür ederim, sorunumla en içten ilgilendiğin için. elzem bir durum olmasına rağmen bu forumdan o kadar çok faydalandım ki projeyi forum sayesinde tamamladığımı, güzel ve kullanışlı bir program haline geldiğini itiraf etmeliyim. bu sorunun çözümünü özel yerine burada yine herkesin faydalanabileceği şekilde çözersek daha iyi olacak, bu durumu yaşayabilecekler için daha faydalı olabilecek kanaatindeyim ve teklifin için teşekkür ediyor geri çevirdiğim içinde özür diliyorum.

ibexpert tarafında eski tabloyu verileri ile birlikte çalıştırılabilir script olarak export ettiğimde, örnek olarak eski tabloda OLAYID alanının, yeni tabloda OLYID olması sebebiyle ibexpert tarafında run komutu sonrası diğer vt içinde bulunan yeni tabloda alanı bulamayacak veriyi aktarmayacak kanaatine kapıldığımdan açıkçası denemedim.

şöyle bir çözüm geldi aklıma, verileri dataset.recno ile 20 000 -20 000 çeksem. query ye 1 ile 20 000 arasını çek ve kaydet, sonra yine 20 001 ile 40 000 arasını çek ve yeni tabloya kaydet şeklinde aktarsam. mantık sizce olabilir bişimi.

zira fibplus paralı ve pahalı

teşekkür ve saygı ile kolay gelsin.
Şefkat-u Merhamette Güneş Gibi Ol.
Başkalarının Kusurunu Örtmekte Gece Gibi Ol.
Sehavet-u Cömertlikte Akarsu Gibi Ol.
Hiddet-u Asabiyette Ölü Gibi Ol.
Tevazu-u Mahviyette Toprak Gibi Ol.
Ya Olduğun Gibi Görün Ya Göründüğün Gibi Ol.

Resim
esrehmaan

Re: Veri aktarımı-out of memory hatası

Mesaj gönderen esrehmaan »

Sorun değil... Msnden yardım ettikden sonra siz kendiniz isterseniz paylaşırdınız... olsaydı team ile size gösterebilirdim.

Delphiturkiye aileside en az size yardımcı olduğu kadar banada olmuştur. Hepsine teşekkürü borç bilirim...


İbexpert ile tabloyu text şeklinde alabilirsiniz... daha sonrada geri alırken istediğiniz alana yönlendire bilirsinizde bende şuan ibepert kurulu değil ondan tam olarak hakim olamıyorum.

bahsettiğiniz şekildede yine sorun çıkar daha az veriler denemezi gerekecektir. ama ibexpert ile sorun yaşamazsınız
orhancc
Üye
Mesajlar: 585
Kayıt: 24 Ağu 2010 02:14
Konum: İstanbul / Kadıköy
İletişim:

Re: Veri aktarımı-out of memory hatası

Mesaj gönderen orhancc »

kayıtları böyle göndermek yerine insert querysi hazırla ve öyle gönder çok daha hızlı işlem yapıyor.
emin_as
Üye
Mesajlar: 559
Kayıt: 01 Eki 2008 10:05
Konum: izmir
İletişim:

Re: Veri aktarımı-out of memory hatası

Mesaj gönderen emin_as »

Problem algoritmada, firebirdde degil.
Tablonun tümünü açıp, arka arkaya satır satır ekleme yapıyorsun. Sonuç olarak bu kayıtlar hafızada tutuldugundan, hafıza şişiyor. Aktarımı kademeli yapmalısın.

Şöyle bir algoritma işini görür.
Kendi koduna göre değişkenler düzenlemesin.

Kod: Tümünü seç

// IBx Bileşenleri kullanarak hazirlanmiş bir algoritmadır
tbYazma : TIBTable veya TIBDataset;
tbOkuma: TIBTable veya TIBDataset;
eklenenveritabani : TIBDatabase

Kod: Tümünü seç

Sayfa:=0; bitti:=false;eklenen:=0;
Repeat
  // 100 kayıt  seçç 
  tbokuma.sql.text  =   Format(' select * from tabloadi rows %d to %d ', [sayfa*100+1,sayfa*100+100]);
 // Aktarılacak tablonun sıfır sonuç getirecek şekilde seç     
  tbYazma.sql.text: =' select * from yazilacak where id=1';
  tbokuma.active:=True;
  tbYazma.Active:=True;
  if tbokuma.recordcount=0 then bitti:=true;  // okunacak kayit yoksa bitir
  while not tbOkuma.EOF do
  begin
     tbYazma.Insert;
     // alanlari aktar
     tbYazma.Post;
     tbOkuma.Next;
     Inc(eklenen);
  end;
  if eklenen > 0  then
  begin
    eklenenveritabani.ApplyUpdates([tbYazma]);
    eklenenveritabani.Connected:=false;
    eklenenveritabani.Connected:=True;
    eklenen:=0;
    Application.ProcessMessages;
  end;      
 Until bitti;
Bu kod milyonlarca da olsa kayıtları sorunsuz aktaracaktır.
Başlangıçta veritabanı baglantılarını düzenleyip, açmalısın.
Her 100 kayıttan sonra yazılan veritabanı açılıp, kapanacaktır. Bu transactionların tamamlanması için uygun bir davranıştır.
Hızın sorun olacagını sanmıyorum, çok hızlı birşey istiyorsan ibsql ile insert sqlleri oluşturabilirsin.
Cevapla