nach ExecSQL(ADOQuery) Speicherplatz wieder freigeben



  • Hallo,

    ich möchte Euch nochmals um Eure Mithilfe bitten.
    Ich habe auf meiner Form eine ADOConnection und eine ADOQuery.
    Beim Start der Anwendung wird die Verbindung zur Datenbank hergestellt und die Query mit der Datenbank verbunden.

    __fastcall TF_Main::TF_Main(TComponent* Owner)
            : TForm(Owner)
    {
       AnsiString ConString;
    
       ConString = "..."
    
       ADOConnection1->ConnectionString = ConString;
       ADOConnection1->Connected=true;
       ADOConnection1->Open();
       ADOQuery1->Connection = ADOConnection1;
    }
    

    Ist in meiner Anwendung der Protokollmodus aktiviert, so protokolliert diese ihre Aktivitäten in einer Access-Datenbank. Hierfür wird dann an diversen Stellen folgende Funktion aufgerufen:

    void protokoll (AnsiString text)      
    {
       AnsiString sqlstring = "";
    
       sqlstring = "SELECT '";
       sqlstring += uhrzeit("sql");
       sqlstring += "', '";
       sqlstring += text;
       sqlstring += "';"; 
    
       F_Main->ADOQuery1->SQL->Clear();
       F_Main->ADOQuery1->SQL->Add("INSERT INTO Protokoll ");
       F_Main->ADOQuery1->SQL->Add("( Datum, PText ) ");
       F_Main->ADOQuery1->SQL->Add(sqlstring);
       F_Main->ADOQuery1->ExecSQL();
    }
    

    Nun frisst diese Funktion etwas Speicher. Es ist nicht viel, aber ich würde dennoch gerne richtig und vollständig programmieren.
    Zum Verbrauch:
    Wenn ich die letzten 5 Zeilen auskommentiere und die Funktion 100.000 Mal aufrufe, dann steigt die Speicherauslastung (laut TaskManager) zwischen Programmstart und dem letzten Lauf um 4 KB. Also alles bestens ok.
    Wenn ich die Funktion wie oben dargestellt (also ohne Auskommentierung der letzten 5 Zeilen) 100.000 Mal aufrufe, dann steigt die Speicherauslastung zwischen Programmstart und dem letzten Lauf um mehr als 3 MB.

    Wie gesagt es geht mir nicht um die 3 MB, mehr um eine korrekte Programmierung und dass ich beanspruchten Speicher, den ich nicht mehr benötige, auch wieder freigebe. Leider habe ich in der BCB-Hilfe (und auch hier im Forum) nichts dazu gefunden.
    Und ich kann an dieser Stelle nicht verstehen, was den Speicher verbraucht.
    Die Verbindung zur Datenbank wird nur einmal definiert und bleibt unverändert.
    Der AnsiString sqlstring wird bei jedem Aufruf neu initialisiert, SQL wird bei jedem Aufruf geleert.

    Was belegt hier den Speicher und wie kann ich diesen wieder freigeben?

    Vielen Dank für Eure Antworten.



  • Der TaskManager ist kein geeignetes Tool um die Speicherauslastung eines Programms zu ermitteln.
    Borland Programme verwenden unter anderem einen eigenen Speichermanager, der sobald Speicher benötigt wird diese Anforderung aus einem internen Pool bedient. Wenn der Pool leer ist, wird Windows um Speicher gefragt. Umgekehrt wird aber nicht unmittelbar der Speicher an Windows zurückgegeben, wenn Du irgendwo ein "delete" aufrufst sondern erstmal nur im Pool als frei markiert, so dass die nächste Anforderung dann ggf. direkt aus dem Pool bedient werden kann.

    Für Dich bedeutet das: vermutlich ist alles in bester Ordnung und Du hast kein Speicherleck.


Anmelden zum Antworten