Announcement

Collapse
No announcement yet.

Speicherverwaltung

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Speicherverwaltung

    Hallo,

    ich muss relativ große Datenmengen verarbeiten und lese die aus einer mysql Tabelle in ein Dataset. Der Speicherverbrauch steigt dann auf ca. 1 GB, was ja noch ok, da einkalkuliert ist. Nur werde ich nun den verbrauchten Speicher nicht mehr los und wenn ich ein weiteres Mal Daten anfordere, dann kommt eine "Out of Memory Exception". Ich habe schon alles mögliche versucht, aber der Speicher bleibt so lange belegt, bis das Programm beendet wird. Eigentlich dachte ich, dass die Garbage Collection den Speicher aufräumen müsste, wenn ich eine Variable auf NOTHING setze. Ich verwende nach wie vor VS2001/VB.NET.

    Ich hoffe, mir kann da jemand weiter helfen. Danke schon mal im Voraus

    Markus

  • #2
    Wie greifst Du den auf MySQL zu?
    Und etwas Code wäre auch von Vorteil

    Comment


    • #3
      Ich verwende den MySQL Connector/NET V1.0.4, aber ich vermute, das ist nicht das eigentliche Problem, da es eben bei beliebigem Speicherverbrauch auftritt, z.b. wenn ich eine Hashtable entsprechend auffülle. Wenn ich die Variable auf NOTHING setzte und dann eine weitere fülle, steigt der Speicherverbrauch kontinuierlich an. Es sieht nicht so aus, als ob jemals der Speicher aufgeräumt wird.

      Dim dbCon As New MySqlConnection()
      Dim dbCmd As New MySqlCommand()
      Dim dbDA As MySqlDataAdapter
      Dim ds As DataSet

      dbCon.ConnectionString = "Data Source=localhost;User Id=user;Password=password"
      dbCmd.Connection = dbCon
      dbCon.ChangeDatabase("testdb")

      Do
      ds = New DataSet()
      dbDA = New MySqlDataAdapter()
      ......
      dbCmd.CommandText = "Select HIGH_PRIORITY SQL_BIG_RESULT datetime,xad,yad,duration,cause_from FROM test WHERE datetime LIKE '" & datum & "%'"
      dbDA.SelectCommand = dbCmd
      dbDA.Fill(ds, "test")
      ....
      ....
      ds.Dispose()
      dbDA.Dispose()
      ds = Nothing
      dbDA = Nothing
      Loop ..

      Comment


      • #4
        Hallo,
        bei den Fällen, wo ich dieses Verhalten beobachten konnte, war immer unmanged Code im Spiel (Beispiel: Die BDP.NET-Komponenten von Borland, die direkt auf die Win32-DLLs von dbExpress zugreifen und bei jedem Aufruf ca. 0,5 MByte RAM "verbraten"). Der Garbage Collector von .NET kontrolliert nur den managed Code

        Comment


        • #5
          wenn dem so wäre ...

          ich habe jetzt extra nochmal einen test geschrieben und der speicher wird definitiv nicht aufgeräumt, weder nach dem .Clear noch nach einem .Dispose und da ist kein unmanaged Code.
          Also entweder verstehe ich etwas nicht und/oder ich mache etwas falsch.

          Sub TestLcr() As Boolean
          Dim dbCon As New MySqlConnection()
          Dim dbCmd As New MySqlCommand()
          Dim dbDA As New MySqlDataAdapter()
          Dim ds As DataSet
          Dim x As Integer = 0
          Dim CID As Integer = 0
          Dim row As DataRow
          Dim iTLCR As Hashtable
          Dim TLcr1() As stLcr

          dbCon.ConnectionString = "Data Source=localhost;User Id=admin;Password=beamup"
          dbCon.Open()
          ds = New DataSet()
          dbCon.ChangeDatabase("pm2_lcr")
          dbCmd.Connection = dbCon
          dbCmd.CommandText = "Select HIGH_PRIORITY SQL_BIG_RESULT prefix, Name FROM lcr3 GROUP BY Prefix"
          dbDA.SelectCommand = dbCmd
          dbDA.Fill(ds, "LCR")
          LcrSize = (ds.Tables("LCR").Rows.Count * nofActCarriers) - 1
          ReDim TLcr1(LcrSize)
          CID = 0

          Do
          If nCarriers(CID).CID > 0 Then
          For Each row In ds.Tables(0).Rows
          TLcr1(x).Code = nCarriers(CID).Switch_Name + row(0)
          TLcr1(x).Name = row(1)
          x += 1
          Next
          End If
          CID += 1
          Loop Until CID > nofCarriers

          dbCon.Close()
          iTLCR = New Hashtable(LcrSize, 0.8)
          For x = 0 To LcrSize
          iTLCR.Add(TLcr1(x).Code, x)
          Next

          ds.Clear()
          iTLCR.Clear()
          TLcr1 = Nothing
          ds.Dispose()
          ds = Nothing
          iTLCR = Nothing
          GC.Collect()
          GC.WaitForPendingFinalizers()

          End Functio

          Comment


          • #6
            Wieviel Speicher ist denn in der Maschine drin? Unter Umständen erkennt das Framework wegen zuviel Speicher einfach nicht die Notwendigkeit vom GC und die Fehlermeldung ist ein übervorsichtiger Schutz von der MySQl Komponente? <p>
            Mari
            Schöne Grüße, Mario

            Comment


            • #7
              Es sind 2 GB im Rechner, aber der wird während der Berechnung auch gebraucht. Wenn der Speicherverbrauch ansteigt kommt eben irgendwann die OutOfMemoryException, d.h. .NET erkennt durchaus, dass kein Speicher mehr da ist, unternimmt aber nichts dagegen

              Comment


              • #8
                Hallo,
                <br>
                &gt;..und da ist kein unmanaged Code...
                Diese Aussage wäre nur dann uneingeschränkt gültig, wenn aus dem Testprogramm <b>jeder</b> Verweis auf die Assemblies von MySqlConnection, MySqlCommand und MySqlDataAdapter <b>entfernt</b> werden, um die DataSet-Instanz zur Laufzeit als In-Memory-Tabelle direkt selbst zu füllen.
                <br>
                &gt;..aber der Speicher bleibt so lange belegt, bis das Programm beendet wird...
                In diesem Fall räumt Win32 über den Prozess komplett ab (auch die Leichen, die durch unmanged code entstehen).

                Comment


                • #9
                  ich dachte, der MySQLConnector/NET wäre managed code. Ist dem nicht so. Wie kann man so was feststellen

                  Comment


                  • #10
                    Ich habe die Aussage vom MySQLConnector auch so verstanden, dass diese Bibliothek, da komplett in C#, managed ist...<p>
                    Ist der MySQl-Server extern, dass ausgeschlossen werden kann, dass die Meldung von ihm kommt?<p>
                    Dann wäre noch ein Versuch, den Speicher auf 1GB mal runterzufahren. Hat nicht jede Anwendung nur 2GB Speicher zur Adressierung zur Verfügung? Zusammen mit der Auslagerungsdatei könnte ich mir so vorstellen, dass .Net wesentlich optimistischer ist, was den Speicherverbrauch angeht und so die Max-Größe für den Anwendungsspeicher höher ansiedelt, als die Komponente verwalten kann.<p>
                    Mari
                    Schöne Grüße, Mario

                    Comment


                    • #11
                      Hallo,

                      &gt;..ich dachte, der MySQLConnector/NET wäre managed code. ..

                      nicht ohne Grund habe ich das Beispiel von BDP.NET verwendet, denn Borland bezeichnet diese Klassen auch aus "native" .NET-Zugriffswege (auch wenn die eigentlichen Funktionen aus Win32-DLLs ausgeborgt werden). Im .NET Framework 1.1 greift ja sogar SqlConnection intern auf MDAC (Win32 COM-Objekte) zurück - erst im .NET Framework 2.0 ändert sich das.
                      <br>
                      &gt;Wie kann man so was feststellen?
                      Indem das Programm auf einem frisch installierten Rechner gestartet wird, auf dem kein MySQL-Client installiert ist. Wenn dann alle über XCOPY installierten DLLs auch .NET-Assemblies sind, wäre es in der Tat eine native .NET-Anwendung

                      Comment


                      • #12
                        Danke, das ist eine Idee, ich werde mal die Auslagerungsdatei entfernen und heute Abend die Ergebnisse mitteilen

                        Comment

                        Working...
                        X