Ein größeres Datenbank-Projekt beinhaltet einen Ausdrucksparser (der also numerische Ausdrücke wie x^2+100/6 erkennen kann, einschließlich von Symbolen und Stringverarbeitung). Der Parser ist ein nicht visuelles Objekt (ohne form und alles), der neben den Datenstrukturen die Funktionen des Parsers enthält, also Scannen, Parsen, Baum aufbauen, Baum abarbeiten, Baum wieder zerstören. Nicht triviale, aber sehr bodenständige Programmierung.
Die Speicherverwaltung ist natürlich dynamisch, da der Parser sich durch die Formel frißt und einen Ereignisbaum aufbaut, der dann bei der Abarbeitung rekursiv abgearbeitet wird. Speicher wird via getmem beantragt und freemem freigegeben; diese Proceduren sind allerdings gekapselt, um (1) Fehler abzufangen zu können, und (2) optional zu Testzwecken in ein Logfile schreiben, ob eventuell irgendwo Speicher beantragt, aber nicht freigegeben wurde.
Dieser Parser liegt 'unterhalb' eines Datenbankinterpreters. Wenn nun der Datenbankinterpreter z.B. einen Befehl bekommt wie
MOV betrag,x*1.16 (tue x*1.16 nach 'betrag')
schaut er nach, ob 'betrag' eine gültige Variable (oder ein Datenfeld) ist und löst mit Hilfe des Parsers den rechts stehenden Ausdruck auf. Dazu wird ein Parserobjekt dynamisch erzeugt, also via [gekapseltem] getmem(pPa,ParserObject). Dann wird fröhlich mit pPa der Ausdruck aufgelöst, der Ereignisbaum aufgebaut, eventuell mehrfach im Laufe des Interpreterprogramms abgearbeitet und am Ende freigegeben. Die Freigabe geschieht mit einem destructor, der allen vom Parser selber beantragten Speicher freigibt, und dann selbst via freemem(pPa,ParserObject) entfernt wird.
Das funktioniert auch alles fabelhaft (und zwar seit Jahren), aber nun habe ich festgestellt, dass dem guten Parser bei jedem Aufbau des Parserbaums etwa 16KB verloren gehen. Ich sehe das nur im Windows-Taskmanager, wo sich bei einem komplexen Programm des Interpreters der vom Programm belegte Speicher rasend schnell erhöht. Detailtest zeigen mir dann, dass an dem Punkt, wo der Parser ein array von ca 64 KB freigeben soll (via freemem), nur 48 KB bei Windows wieder ankommen; 16 KB verschwinden.
Ich mußte das alles so genau erklären, um klar zu machen, dass ich nicht irgendwo 'vergessen' habe, Speicher wieder freizugeben. Wie gesagt, getmem und freemem sind gekapselt und können überwacht werden (man kennt das ja bei großen Projekten).
Als Systemprogrammierer würde ich sagen, dass die Garbage-collection ein bißchen buggy ist, aber das kann doch wohl nicht sein, oder ? Der Parser hantiert auch mit long-strings, kann das eine Ursacher sein ? Muss ich das Objekt, dass ich mit einem schlichten [gekapselten] getmem initialisiere (und mit freemem wieder freigebe) noch irgendwie anders ins Nirwana schicken ?
Ich arbeite mit Delphi 4.0 und danke für jeden Hinweis.
Hanz