Programm müllt den Speicher voll aber warum?

nero-15

Grünschnabel
Hallo,
ich habe folgendes Progrämmchen geschrieben, um Daten ausm Internet zu laden. Leider wird die Auslagerungsdatei vollkommen zugemüllt und ich verstehe nicht warum. Ich habe keine Variablen-Initialisierungen in einer Schleife und ich gebe auch die Resourcen aller Streams wieder frei. Vielleicht kann mir jemand ja einen Tip geben. Das Problem ist, dass das Programm sehr lange laufen soll, da viele Daten heruntergeladen werden sollen...
Fällt jemandem auf, wo sich die überflüssigen Daten ansammeln?
Ich nutze Visual Basic Express 2008 auf Win XP.

Visual Basic:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        'Wurzelverzeichnis ersetllen
        Dim rootPath As String = TextBox3.Text
        createDirectory(rootPath)

        ' Variablendeklaration für die For Schleife
        Dim seite As String
        Dim i As Integer
        Dim seitenStream As Stream
        Dim sr As StreamReader
        Dim site As String
        Dim artikel As String
        Dim titel As String
        Dim rawDate As String
        Dim datumArray() As String
        Dim year As String = ""
        Dim datum As String
        Dim text As String
        Dim nummer As String
        Dim teil As String
        Dim dateiname As String
        Dim sw As StreamWriter
        Dim errorWriter As StreamWriter

        ' bekommt den Startwert aus einer Textbox und rattert dann los
        For i = TextBox2.Text To TextBox4.Text

            Try
                seite = "szukaj.gazetawyborcza.pl/archiwum/1,0," & i & ".html"
                WebBrowser1.Navigate(seite)
                TextBox1.Text = seite

                ' Hier wird gewartet bis der Browser fertig geladen hat
                While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete
                    'Debug.WriteLine(WebBrowser1.ReadyState)
                    Application.DoEvents()
                End While

                ' Datei wird als Stream zum lesen bereitgestellt
                seitenStream = WebBrowser1.DocumentStream
                sr = New StreamReader(seitenStream, Encoding.GetEncoding("iso-8859-2"))

                ' Die Seite wird geleseun und in ihre relevanten Bestandteile zerlegt
                site = sr.ReadToEnd()
                artikel = cut(site, "<artykul>", "</artykul>")
                titel = cut(artikel, "<tytul>", "</tytul>")
                rawDate = cut(artikel, "</mutacja>", "</metryczka>").Substring(8, 19)
                datumArray = Split(rawDate, "/")
                year = datumArray(2).Substring(0, 4) ' Beim auslesen muss noch eine Restzeichenkette vom Jahr weggeschnitten werden
                datum = year & "-" & datumArray(1) & "-" & datumArray(0)
                text = cut(artikel, "<tekst>", "</tekst>")
                text = removeTags(text)
                nummer = cut(artikel, "<numergazety>", "</numergazety>")
                teil = cut(artikel, "<mutacja>", "</mutacja>")

                ' Prüfen ob ein Ordner mit der Jahreszahl existiert und sonst erstellen
                createDirectory(rootPath & year)


                ' Der Titel Wird bearbeitet um ihn für den Dateinamen kompatibel zu machen
                'Dim laenge As Integer = 20
                'If titel.Length < laenge Then
                'laenge = titel.Length
                'End If
                'Dim titelKurz As String = titel.Substring(0, laenge)
                'titelKurz = Replace(titelKurz, "/", "")
                'titelKurz = Replace(titelKurz, "\", "")
                'Dim shortTitle As String = "[" & titelKurz & "...]"

                ' Dateiname wird erstellt
                dateiname = datum & " GW " & nummer & " " & i & ".txt"

                ' Daten werden in die Datei geschrieben
                sw = New StreamWriter(rootPath & year & "\" & dateiname)
                sw.WriteLine("Datum: " & datum)
                sw.WriteLine("Titel: " & titel)
                sw.WriteLine("Nummer: " & nummer)
                sw.WriteLine("Teil: " & teil)
                sw.WriteLine("Text: " & text)
                sw.WriteLine()
                sw.WriteLine(artikel)

                'Streams schließen
                seitenStream.Dispose()
                sr.Dispose()
                sw.Dispose()

                'Iterationsschritt(anzeigen)
                TextBox2.Text = i
            Catch ex As Exception
                Try
                    errorWriter = New StreamWriter(rootPath & "error.txt", True)
                    errorWriter.WriteLine("Fehler in Datei: " & year & " " & i)
                    errorWriter.Dispose()
                Catch

                End Try
            End Try

        Next

    End Sub
 
Zuletzt bearbeitet:
anstatt .Dispose() zu verwenden ist glaube die Verwendung von using besser.
Und vielleicht auch noch GC.Collect() aufrufen.
 
Vielen Dank für die schnelle Antwort.

GC.Collect() habe ich wie folgt verwendet. Nur leider scheint es nichts zu bringen

Visual Basic:
If i Mod 500 = 0 Then
     GC.Collect()
End If

Nach Microsoft :
sind folgende Codezeilen gleichbedeutend

Visual Basic:
Using resource As New resourceType 
    ' Insert code to work with resource.
End Using

Visual Basic:
Dim resource As New resourceType
Try 
    ' Insert code to work with resource.
Catch ex As Exception
    ' Insert code to process exception.
Finally 
    ' Insert code to do additional processing before disposing of resource.
    resource.Dispose() 
End Try

Also scheint .Dispose() genau das gleiche zu bewirken...
Vielleicht noch einen Tip auf Lager?
 
meine nur gehört zu haben das mit using der Speicher schneller frei geräumt wird.

Was macht eigentlich die Funktion cut?

Wenn ich das richtig sehe ließt du Xml Dateien aus, wäre es da nicht besser System.Xml.XmlDocument zu verwenden?
 
Die Funktion schneidet den ersten durch zwei Trennzeichen eingeschränkten Teilstring aus einem String
Visual Basic:
    ' schneidet den ersten String der zwischen den zwei Trennmarken vorkommt aus einem String
    Public Function cut(ByVal s As String, ByVal start As String, ByVal ende As String) As String
        Dim cut1() As String = Split(s, start)
        Return Split(cut1(1), ende)(0)
    End Function

Jetzt wo dus sagst. Ich werde da mal ein using einbauen vielleicht hilft das weiter. Könnte ja sein, dass er die ganzen cut1() Arrays im Speicher behält. Allerdings frage ich mich dann, warum der Garbage Collector die nicht rausschmeißt...


Ich habs jetzt mit einem
Erase cut1 gemacht
bringt aber leider auch nichts...
 
Zuletzt bearbeitet:
Dann ist meine letzte Vermutung das es vielleicht am WebBrowser liegt, vielleicht kann man da ja noch irgendwas optimieren, aber so viel hab ich mit dem noch nicht gemacht.

Im übrigen wird der Speicher auch automatisch geleert wenn du das Fenster minimierst.
 
hi,


also um mal den browser auszuschließen würde ich einen webrequest /webresponse verwenden oder den webclient.


und dann frage ich mich warum du den split operator verwendest.
ich dachte der legt sowieso ein array an und damit speicher.

warum nimmst du nicht substring und dann mit index of ?
oder regular expression ?

hoffe ich konnte dir helfen !

mfg
Martin
 

Neue Beiträge

Zurück