# Speicher freigeben



## spirit (10. Dezember 2009)

Hallöchen

Ich habe da mal wieder ein kleines Problem...

Ich habe einen Ordner in dem in Unterverzeichnissen ca. 100.000 nach einem Chema gespeichert, bei dem ich mit einem Schlagwort die Bilder zum entsprechenden Thema finde. Damit es nicht immer eine Ewigkeit dauert habe ich mir eine MySql Datenbank erstellt, in der mit einer Schleife und dem Filesystemobject die Ordner rekursiv durchsucht und eingetragen werden. Das funktioniert prächtig. 

Leider hat diese Schleife aber den NAchteil, das der Arbeitsspeicher bei jedem Durchlauf kontunuierlich voll läuft. Das waren zuletzt fast 1,9 GB !

Daher meine Frage: Gibt es einen Befehl der den Arbeitsspeicher "entlastet" ?

So als Idee...Führe Schleife aus und gebe die Ressourcen wieder frei

Im voraus vielen Dank!!


----------



## Yaslaw (11. Dezember 2009)

Zeig doch mal ein wenig Code, damit wir einen Ansatz haben mit welchen VB-Methoden du da arbeitest


----------



## spirit (14. Dezember 2009)

Bitte schön..;-))


```
Private Sub eintragMP3(ByVal song As String)
        
    '// Verbinung herstellen
    oConn.OpenConnection HOST, USER, PASS, DB
    
    '// Songtitel in Statusbar angeben
    StatusBar1.Panels(1).Text = "Trage ein: " & song
   
    '// Einfache Slash gegen doppelte Slash tauschen
    strDBfile = Replace(song, "\", "\\")
       
    '// Datenbank störende Zeichen ersetzen
    strDBfile = Replace(strDBfile, "'", "")
    strDBfile = Replace(strDBfile, "´", "")
    strDBfile = Replace(strDBfile, "`", "")
        
    '// Titel und Pfad zerlegen
    ssong = Split(strDBfile, "\\")
    nameSong = ssong(UBound(ssong))
    nameSong = Replace(nameSong, ".mp3", "")
    
    '// Prüfen ob DAtei schon in Datenbank vorhanden
    Set oRs = oConn.Execute("select * from " & TABLE & " where name = '" & nameSong & "' and pfad = '" & strDBfile & "'")
    
    '// Anzahl prüfen
    If oRs.RecordCount > 0 Then GoTo errHnd
    
    '// Titel in Datenbank eintragen
    oConn.Execute ("insert into " & TABLE & " (name, pfad, chksumm, playcount) values ('" & nameSong & "','" & strDBfile & "','#',0) ")
    DoEvents
    
    
    '// Fehler abfangen
    If oConn.Error.Number = 0 Then
        
        '// Anzahl der in der Datenbank gesoeicherten Songs
        Set oRs = oConn.Execute("select * from " & TABLE & "")
        
        '// Anzahl ausgeben
        lblSave.Caption = oRs.RecordCount
        
    Else
    
        '// Anzahl Erro Dateien ausgeben
        lblError.Caption = lblError.Caption + 1
        
    End If
    
errHnd:

    '// Recordset freigeben
    Set oRs = Nothing

    '// Datenbankverbindung schliessen
    oConn.CloseConnection
    
End Sub
```

Hier wird einfach ein Pfad übergeben der eingetragen werden soll.


----------



## Yaslaw (14. Dezember 2009)

Arbeitest du mit ADO, DAO, ODBC oder mit was?

item: Den Recordset solltest du schliessen bevor du in mit Nothing oder einem neuen Inhalt überschreibst (Call oRs.close)
item. Wozu den oRs.FillCache ? Den brauchst du da mMn nicht. Frisst auch nur speicher.


----------



## spirit (14. Dezember 2009)

Danke für deine Antwort. 

Ich arbeite mit einer dll mit der es möglich ist MySql DAtenbanken direkt anzusprechen.
Habe die Recodset explicit geschlossen. Bingt aber auch nichts. Wie kommst du auf



> oRs.FillCache ?



Nach jedem Eintrag in die Datenbank sind ca 100kB Speicher mehr belegt.


----------



## Yaslaw (14. Dezember 2009)

spirit hat gesagt.:


> Bingt aber auch nichts. Wie kommst du auf
> oRs.FillCache ?



Ups, mein Fehler. Ist da reingerutscht als ich im VBA die methoden von DAO.Recordset durchsuchte und nachher hab ich nicht mehr gemerkt das es von mir ist (telefonische Ablenkung).

Es gibt noch 2 Orte wo ich etwas vorstellen kann.
1) das dll gibt den Speicher nicht frei -> Doku zum dll sollte auskunft geben wie man den Speicher frei gibt.
2) du löst die Liste nicht sauber auf, wo die Files durchgeackert werden. Der Speicherverbrauch ist dann nicht auf Seite MySQL/dll sonder im Code von dir. Dies kann ich aber anhand des geposteten Codes nicht beurteilen


----------



## spirit (14. Dezember 2009)

mehr Code gibt es da nicht...der geposteten Prozedur wird lediglich ein pfad aus einem FileSystemObjekt übergeben.....


----------



## Yaslaw (14. Dezember 2009)

spirit hat gesagt.:


> mehr Code gibt es da nicht...der geposteten Prozedur wird lediglich ein pfad aus einem FileSystemObjekt übergeben.....


Nicht nur ein Pfad, sondern ein Pfad nach dem anderen. Räumst du dort jeweils sauber auf? Arbeitest du mit einer Collection?


----------



## spirit (14. Dezember 2009)

Aus einer Dirbox übergebe ich per Klick den Pfad:


```
Private Sub cmdSuche_Click()
    
    '// Objektzuweisung
    Set objFSO = New Scripting.FileSystemObject

    '// Dateien suchen
    FindFiles Dir1.Path, "*.mp3"
    
    '// Variable initialisieren
    lngCount = 0
        
End Sub
```

mit dem Aufruf wird der Startpfad übergeben:


```
Private Sub FindFiles(ByVal vsFolderPath As String, ByVal vsSearch As String)

    '// Verweis auf den zu durchsuchenden Ordner setzen:
    Set objFolder = objFSO.GetFolder(vsFolderPath)
  
    '// Alle Dateien mit allen Attributen suchen
    strFileName = Dir$(objFSO.BuildPath(objFolder.Path, vsSearch), _
                  vbNormal Or vbHidden Or vbSystem Or vbReadOnly)
                  
    '// So lange Dateien im Ordner vorhanden sind...
    Do While Len(strFileName) > 0
      
        '// Zaehler erhöhen
        lngCount = lngCount + 1
      
        '// Anzahl ausgeben
        Label5.Caption = lngCount
      
        '// Dateinamen übergeben
        strFile = objFSO.BuildPath(objFolder.Path, strFileName)
              
        '// Statusbar rot markieren
        Shape1.BackColor = &HFF&
        DoEvents
      
        '// Datei in Datenbank eintragen
        eintragMP3 strFile
        
        '// Warteschleife für 1 Sekunde
        'Sleep (20)
      
        '// Statusbar wieder grün markieren
        Shape1.BackColor = &HFF00&
        DoEvents
      
        '// Zähler für Dateien erhöhen
        lngFileCount = lngFileCount + 1
      
        '// Nächste Datei suchen
        strFileName = Dir$()
      
    Loop
    
    '//Wenn Unterordner vorhanden sind...
    If objFolder.SubFolders.Count > 0 Then
    
        '// Alle Unterordner durchsuchen...
        For Each objFolderLoop In objFolder.SubFolders
          
            '//Funktion erneut aufrufen
            FindFiles objFolderLoop.Path, vsSearch
                                    
        '// nächstes Objekt
        Next objFolderLoop
        
        If objFolderLoop Is Nothing Then GoTo errHnd
           
    End If
    

    Exit Sub
   
errHnd:
  
    '// Verbinung herstellen
    oConn.OpenConnection HOST, USER, PASS, DB
    
    '// Anzahl Datenbankeinträge auslesen
    Set oRs = oConn.Execute("select name from " & TABLE & "")
    
    '// Anzahl ausgeben
    lblSave.Caption = oRs.RecordCount
    
    '// Recordset schliessen
    oRs.CloseRecordset
    
    '// Recordset freigeben
    Set oRs = Nothing
    
    '// Dartenbankberbindung trennen
    oConn.CloseConnection
    
    '// Meldung ausgeben
    MsgBox "Fertig...", vbOKOnly + vbInformation, App.Title
    
    
End Sub
```

Ohne den Eintrag:


```
eintragMP3 strFile
```

bleibt der Speicher konstant. Also muss es etwas mit der Mysql DB zu tun zu haben


----------



## tintin (31. Mai 2010)

Hallo spirit,

hast Du eigentlich eine Antwort auf Dein Problem:
                            >>>>>Nach jedem Eintrag in die Datenbank sind ca 100kB Speicher mehr belegt.
bekommen?

Ich habe nämlich genau das gleiche und weiss nicht weiter.
Gruß tintin


----------

