Out of Memory (Firebird/Interbase 2.5.2)

Out of Memory (Firebird/Interbase 2.5.2)
2014-03-21T08:30:29+01:00
2014-03-31T05:01:22+02:00
2022-11-30T20:41:55+01:00
North505
Sziasztok!

Olyan problémában kérném a segítségeteket, hogy van egy Delphi 6-ban fejlesztett program, IB komponensekkel, Firebird 2.5.2 adatbázismotorral használva. 

Az adatbázis kezeléshez IBExpert-et használok. Az IBExpert-ben és a programban (futás időben) előfordul - hozzáteszem véletlenszerűen - Out Of Memory hibaüzenet és nem tudom mi okozza ezt.

Az adatbázis kb. 350-400 MB, 260 tábla amelyek közt van pár (10-12) ami 50000 record körüli és 250-280 oszlopot (varchar,double,integer,blob) tartalmaz.

Annyit tudok, hogy abban az esetben tudom előidézni a hibát - de itt sem mindig - amikor a fent említett "nagy" táblákban az első recordról CTRL+End -vel a végére megyek a táblának. Ilyenkor elkezdi fetch-elni az adatokat és egy idő után Out Of Memory. Valamikor az első ilyen tábla fetchelése esetén, valamikor viszont csak a 2. 3. tábla fetchelése esetén keletkezik a hiba.

Gyanítom, hogy ha már itt adatbázis szinten elő tudom idézni a hibát, akkor a Delphi forrással is IB komponensekkel nem lehet gond. A Firebird helpekben nem találtam semmit erre vonatkozólag.

Várom mindenki segítő válaszát.

Előre is köszönöm.
Mutasd a teljes hozzászólást!
Speciel a blob használat a varachar helyett az segít elkerülni az OoM-et IBX esetén mert akkor csak a BlobID kerül bele a buffer-be és maga a blob külön memória területre kerül. ;)

memory manager csere + 1 : ScaleMM az isten!
Mutasd a teljes hozzászólást!

  • Ne nyalj fel annyi adatot egyszerre, vagy vegyél még RAM-ot!
    Mutasd a teljes hozzászólást!
  • Szia!

    Virtuális memória felső mérete korlátozva van az op. rendszerben?



    Elméletileg nem szabadna... tény, hogy mindent betölt a kliens gép memóriájába, javallott nagy rekordszámú táblák teljes nézetét nem engedni programon belül, (nem fogja egyesével végignézni... terheli a klienst, a szervert, a hálózatot, stb.)



    BySzi
    Mutasd a teljes hozzászólást!
  • Szia!

    A lapozófájl méretének automatikus kezelése minden meghajtón van beállítva.
    Mutasd a teljes hozzászólást!
  • "Elméletileg nem szabadna... tény, hogy mindent betölt a kliens gép memóriájába, javallott nagy rekordszámú táblák teljes nézetét nem engedni programon belül, (nem fogja egyesével végignézni... terheli a klienst, a szervert, a hálózatot, stb.)"

    Az a baj hogy ha erre a viszonylag nagy adattáblára egy selectet kérek le, melynek eredménye egyetlen sor a maga 250 körüli adatszámával, akkor is időnként kiakad Out of Memoryval a program.
    Mutasd a teljes hozzászólást!
  • Üdv!

    Az IBX memória foglalási stratégiája borzalmas.

    Lehetséges megoldások :
    #1: Ha tutod hány recordod lesz előre, akkor a BufferChunks állítás sokat tud segíteni.
    InterBaseExpress: Tips and Tricks

    #2 : Ha tudsz, akkor használj helyette IBO-t, ott nincs ilyen gond. 

    #3 : Húzd át az adatokat TClientDataSet-be, úgy hogy a TIBQuery-d UniDirectional, a CDSnél sincs OoM gond.



    PS :
    - az IBO gyorsabb is mint az IBX
    - az IBX offical nem támogatja az FB1+ verziókat. Ugyan nekem még XE4 x64 alatt sem volt vele gondom, de pl FB30-tól már depricated lesz a régi FB API.
    Mutasd a teljes hozzászólást!
  • ...és kerüld a "select * from table" lekérdezést!

    Mindig csak azokat a mezőket kérd le, amikre szükséged van!
    Mutasd a teljes hozzászólást!
  • Szia!

    Arra gondoltam én is, hogy az IBX-el lehet a baj. A Delphi-ben is IB-s komponenseket használok. Azt viszont nem tudom mi az az IBO.





    Szerinted megoldás lehet az ha ADO komponenseket használok ODBC-vel?
    Mutasd a teljes hozzászólást!
  • IBO : IBObjects Home Page

    ADO-t nem használtam FB kliensnek, nem tudom megoldás-e.
    Mutasd a teljes hozzászólást!
  • Szia!

    Közben megtaláltam. Köszi.
    Elég a free is vagy meg kell venni?
    Mutasd a teljes hozzászólást!
  • Soha nem használtam ADO-t FireBirdhöz, nem tudok erre mit mondani...
    Személyes véleményem, hogy ne is használj!
    Megint személyes véleményem, hogy ha csak lehet, kerüld az ODBC-t...
    Fölösleges még egy "közvetítő" is az adatbázis és a program közé!

    IBX vagy IBO
    Mutasd a teljes hozzászólást!
  • Ha az IBO jó akkor jó sok dolgom lesz mire átalakítom a forráskódomat,  de úgy látom akkor muszáj lesz bevállalnom.

    Azt viszont még mindig nem értem, hogy az IBExpert miért száll el Out of Memory-val fetchelés közben. Ott nincs IBX. Ezért vagyok bizonytalan és gyanakszom a firebird adatbázismotor nem megfelelő memóriakezelésére is.
    Mutasd a teljes hozzászólást!
  • #1 : Firebird memóriakezelésével nincs gond, ez 100%! (ezt bizonylítja az is hogy IBO-val nincs porbléma tehát a probléma FB független)
    #2 : Az IBExpert IBX-et használ, mégha nem a hivatalosat is, hanem olyat, ami Lazarus alatt is fordul. ;)
    Mutasd a teljes hozzászólást!
  • Megpróbálhatod még a ClientDataSet + unidirectional IBX-et is. Ez is megoldás.
    Mutasd a teljes hozzászólást!
  • Sziasztok!

    Az nem lehet megoldás (hogy a legkisebb időráfordítással járjon a probléma megoldása), hogy mindent hagyok IBX-ben, és egy frissebb IBX verzóval updatelem hátha javították ezt a problémát? 

    Esetleg tudtok ilyen javításról?
    Mutasd a teljes hozzászólást!
  • Nem megoldás a frissítés, még a legújabb IBX is ugyanazt a startégiát használja mint az elődei.
    Ha mindenképp IBX-et akarsz használin akkor vagy BufferChunks vagy ClientDataset a két irány, más választás nincs.
    Mutasd a teljes hozzászólást!
  • Vagy ha mégsem akarsz fizetős IBO-ra váltani, akkor megoldás lehet még az UIB komponens.
    Valójában a Firebird hivatalos oldalán is ezt ajánlják.

    Azonban a legfrissebb változat nem a sf.net oldalán van, hanem a készítőjén:
    http://www.progdigy.com/
    ... de valamiért most az nálam nem jön be. ... úgyhogy marad a 2013/05 változat. Azzal sincs semmi baj.
    _____________
    Ha nem akarsz az egész programodban kicserélni mindent, akkor írd át erre egyedül annál a lekérdezésnél, amelyik a kritikus.
    Ne ijedj meg attól, hogy kicsit más a kapcsolódási szintaxisa a komponensnek, mert attól még egyszerű :)
    Mutasd a teljes hozzászólást!
  • Mellesleg nekem a legnagyobb adatbázisom, amivel dolgozom (12 évnyi anyag) 260Mb.
    A legtöbb tétel egy táblában 1 millió feletti.
    De nem használok Blob-ot és max 50-60 mezőt.
    Sosem volt még ilyen "OoM" hibám, pedig vegyesen XP/Win7-32/64 alatt is dolgozom/tesztelek.

    Ami viszont tény, hogy az IBExpert nagyon nem spórol a memóriával.
    ________________________

    Delphi6 alatt használsz valamilyen memória-menedzselő unit-ot, ami lecseréli a projektedben a Delphi-set? (HASZNOS!)
    Mutasd a teljes hozzászólást!
  • Speciel a blob használat a varachar helyett az segít elkerülni az OoM-et IBX esetén mert akkor csak a BlobID kerül bele a buffer-be és maga a blob külön memória területre kerül. ;)

    memory manager csere + 1 : ScaleMM az isten!
    Mutasd a teljes hozzászólást!
  • Sziasztok!

    Úgy néz ki megoldódik a probléma.
    A varchar blob cserét megprobáltam már korábban. Annyit értem el vele hogy később lett OOM. A megoldás, ahogy E_Pluribus_Unum is monta a memory manager csere.



    Én a QMemory-t találtam, amivel 3 napja zavartalan és OOM mentes a program.



    A ScaleMM jobb mint a QMemory?


    Köszi a válaszokat mindenkinek.
    Mutasd a teljes hozzászólást!
  • Döntsd el magad : scalemm - Fast scaling memory manager for Delphi - Google Project Hosting

    Speciel a ScaleMM TÖBB memóriát eszik mint az alap manager, DE nincs memory fragmentation és emiatt hosszab távon jobban teljesít. Nem mellesleg multithread környezetben agyonver minden más MM-et, közel 1-1-es skálázódása van.

    QMemory-ról nem hallottam, Google szerint már több mint 10 éves, míg ScaleMM friss hús. ScaleMM fork is vannak már (SynScale-mm - mORMot project) illetve nemrég tűnt fel az SAPMM.

    ScaleMM támogatja a DLL-EXE közötti manager megosztást is.

    Mi most tértünk át ScaleMM-re. ;)
    Mutasd a teljes hozzászólást!
  • @E_...
    Akkor bejött a megérzésem, hogy nem használt semmilyen MemoryManager-t, és ez volt a gond. Én spec. FastMM-et használok, sosem volt vele semmi gondom, megszűntek a leak-problémák, stb.
    Azért jó, hogy mégis Te kaptad érte a pontot, mert amiket feljebb írtál, abból én is sokat tanultam.

    Főleg az döbbentett meg, hogy a BufferChunks nem az EGYSZERRE BEOLVASOTT rekordok számát adja meg, hanem a lefoglalt memória szorzatát és hogy ha ez kicsi, akkor az új terület lefoglalásakor nem HOZZÁAD még egy kicsit, hanem újra lefoglal n+1 méretet és átmásolja az egészet mégegyszer... micsoda őrültség! De ez van.
    Mutasd a teljes hozzászólást!
  • Atyaég! Most jövök rá, hogy mennyire jó húzás volt részemről, hogy csak a szükséges méretet adtam meg a táblák VARCHAR mezeinek kiválasztásakor, és nem "hagytam rá" pluszban.
    Ahogy olvasom, annak ellenére, hogy egy ilyen string mező csak néhány karaktert tartalmaz, attól még az IBX lefoglalja a teljes területet neki.
    Tehát ha valaki VarChar(1024)-re vagy netán VarChar(32000)-re definiálta a mezőket a táblák létrehozásakor, (mondván, hogy úgyis csak annyit használ, amennyit szükséges) álmában sem gondolt szerintem arra, hogy az IBX minden esetben lefoglalja a szükséges MAXIMUMOT!

    Pl. ha 1000-re van állítva a BufferChunk, akkor az 1001-dik rekord beolvasásakor egy 1x + 2x = 3x1000 rekordnak lefoglalt területet zabál, ami majdnem 10Mega !

    Nem beszélve mondjuk egy tipikus "select * from VEVOK" -ről, ahol ha a "név", "cím", stb... mezőket jó nagyra definiáltuk, és van kb 100.000 rekordunk... akkor az újrafoglaláskor:
    (100.000 + 101000) * 1024 =  200Mega.
    És ha éppen nincs annyi szabadon, akkor nekiáll a winyó dolgozni a pageFile-ra.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd