Announcement

Collapse
No announcement yet.

Speicher-Probleme

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

  • Speicher-Probleme

    Hallo,

    ich habe ein Problem mit der Speicherverwaltung meines Prgramms. Dieses Programm ist im Grunde eine kleine Anwendung, die im Hintergrund auf bestimmte Anforderungen (die einfach über die Zwischenablage "transportiert" werden) wartet. Wenn eine solche Anforderung eintrifft, wird ein recht umfangreiches und wohl doch eher aufwendiges Formular geöffnet. Beim ersten Mal dauert das auch noch ein, zwei Sekunden, bis es komplett dargestellt wird, aber ab dem zweiten Mal ist es dann deutlich schneller. Offenbar wird es nach Schließen der Form (Close) nicht komplett aus dem Speicher entfernt. Der Nachteil ist eben, dass der Speicherbedarf im Laufe der Zeit zu sehr ansteigt. Ich nahm an, dass der Garbage Collector dann irgendwann doch mal aufräumt, aber offenkundig tut er das nicht.
    Um ehrlich zu sein, ich weiß nicht, ob der Code vollständig managed ist, da ich auch Crystal Reports und ein paar Infragistics-Steuerelemente benutze. Aber selbst wenn er unmanaged ist, muss es doch eine Möglichkeit geben, den Speicher explizit wieder frei geben zu können. Wie bewerkstellige ich das?

    Ich bin für jeden Hinweis dankbar ...


    Dave

  • #2
    Hmm ... ja ... also ... ich bräuchte hier doch dringend eine Lösung oder doch zumindest einen Hinweis oder so. Daher erlaube ich mir mal, mein Anliegen nochmals der geneigten Fachschaft vorzulegen. Wie kann ich, außer einem Form.Close, den Speicher freimachen? Geht das aus der zu schließenden Form selbst überhaupt oder müsste ich derlei aus der aufrufenden Form steuern? Und wenn ja, wie?

    Nochmal zusammengefasst: Eine Form A ruft eine andere Form B auf, die, abgesehen von der einen Zeile Aufruf, sonst nichts weiter zu tun hat mit A. B wird irgendwann mit B.Close geschlossen, und von A aus kann man beliebig viele B's aufrufen. Allerdings steigt der Speicherverbrauch mit jedem B-Aufruf, er scheint die geschlossenen Forms nicht aus dem Speicher zu entfernen. Wie kann ich regelmäßig Speicher freimachen?


    Vielen Dank für - so meine Hoffnung - den ein oder anderen Tipp.

    Dave

    Comment


    • #3
      Hallo Dave,
      für eine konkrete Antwort bist du ein bißchen sehr vage mit der Beschreibung des Problems!
      Gruß Christian

      Comment


      • #4
        Hmm. Tut mir leid, aber ich wüßte nicht, welche Infos explizit noch nötig sind. Welche bräuchte es noch? Ich gebe die gern, das Problem wird zunehmend dringend.

        Es ist ein Visual Studio 2008 Projekt, ich benutze neben den normalen Steuerelementen noch einige Infragistics-Steuerelemente und das Crystal Reports, welches VS mitbringt. Ich kenne mich nicht so aus und weiß nicht, ob das alles managed Code ist oder nicht. Auf jeden Fall ist das Formular (quasi ein Auftragsformular) relativ umfangreich, das erstmalige Öffnen dauert ca. 2-3 Sekunden. Jedes weitere öffnet dann schneller, aber vermutlich, weil die geschlossenen nicht aus dem Speicher geräumt werden (offenbar kostet nicht das "Daten-Holen" so viel Zeit, sondern die Initialisierung der Form). Ist ja ganz gut, aber der Nachteil ist eben, dass das Programm irgendwann 400MB im Speicher verbraucht. Und das geht nicht. Einzige Möglichkeit bisher: Programm beenden und neu starten.

        Es handelt sich quasi um eine MainForm (A), welche die einzelnen Auftragsformulare (B) mit einer Zeile Code startet (ich gebe dem Konstruktor der Form B alle notwendigen Infos als Parameter mit). Dann braucht ja quasi Form A nichts mehr von B zu wissen und B übernimmt alles weitere. B wird dann irgendwann einfach geschlossen (Me.Close, habe auch ein Me.Dispose reingebaut, nutzt nur nix). Meiner Meinung dürften dann keine Verweise mehr auf B vorhanden sein, der Speicher sollte also von der GC freigemacht werden. Passiert aber offenkundig nicht, der Verbrauch schwillt weiter an.

        Es ist sonst nichts gewagtes oder sonstwie bemerkenswertes an der Konstruktion. Ach ja, könnte es damit zusammenhängen, dass ich in B auf einge Variablen aus A zurückgreife (SQL-Connection und ein paar globale Variablen)? Aber wohl kaum, ist ja auch was gängiges.

        Wenn ich mit weiteren Infos dienen kann, gern. Aber ich wüßte jetzt erstmal wirklich nicht, welche noch von Nutzen sein könnten.

        Und ich würde mich über Hilfe wirklich sehr freuen. Danke ...

        Dave

        Comment


        • #5
          Hi Dave,
          deinen Code oder zumindest die wesentlichen Teile daraus wirst du schon herzeigen müssen ....

          Gruß
          Christian

          Comment


          • #6
            Ok, gern, kein Problem.
            Der Aufruf in Form A:
            Code:
                      Dim f_temp As Form = Nothing
                      For Each frm As Form In My.Application.OpenForms
                        If frm.Name = "frmVorgang" AndAlso CType(frm, frmVorgang).lblKopfVNr.Text = txtSuche.Text.Trim Then
                          f_temp = frm
                          Exit For
                        End If
                      Next
                      If IsNothing(f_temp) Then Dim f As New frmVorgang(CInt(txtSuche.Text), aktBenutzer.PersonalNr) Else f_temp.BringToFront()
            Er prüft halt, ob dieser Vorgang bereits geöffnet ist, wenn nicht, dann gibt's 'ne neue Form, wenn doch, wird sie in den Vordergrund geholt.

            Der Konstruktor von B:
            Code:
              Public Sub New(ByVal iVNr As Integer, ByVal PersNr As Int16)  ' bereits vorhandene Vorgangsnummer
                InitializeComponent()
                Lade_Vorgang(iVNr, PersNr)
                Me.Show()
              End Sub
            In Lade_Vorgang() werden eben die Daten aus der DB geholt (SQL-Verbidnung, Datenadapter samt Datenbindung der Steuerelemente usw.). So geht's los:
            Code:
                lblToolStripStatus.Text = "lade Vorgang ..."
                Try
                  Verbindung_Oeffnen(sqlCon)
            
                  ' Daten des Vorgangs laden
                  daVorgang = New SqlClient.SqlDataAdapter("SELECT * FROM Vorgaenge_VBM WHERE VNr = " + iVNr.ToString, sqlCon)
                  daVorgang.MissingSchemaAction = MissingSchemaAction.AddWithKey
                  ...
            Und dann gibt's eben in einem Menupunkt der Form den kurzen Befehl Me.Close(). Und damit er die Sachen auch noch speichert, wenn man die Form über das Kreuz in der Titelleiste zumacht, gibt's auch noch das:
            Code:
              Private Sub frmVorgang_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
                If rowVorgang.RowState = DataRowState.Deleted Then Exit Sub
                gridPositionen.DisplayLayout.ViewStyleBand = Infragistics.Win.UltraWinGrid.ViewStyleBand.OutlookGroupBy
                gridPositionen.DisplayLayout.Bands(0).ColumnFilters.ClearAllFilters()
                gridPositionen.DisplayLayout.Override.FilterUIType = Infragistics.Win.UltraWinGrid.FilterUIType.Default
                tempFeld = "1"
                Daten_Speichern()
                'ToDo: Funktioniert nicht
                gridPositionen.Rows.DeallocateCells(True)
                gridPositionen.DisplayLayout.Bands(0).Columns.Dispose()
                gridPositionen.Rows.Dispose()
                gridPositionen = Nothing
                Me.Finalize()
                Me.Dispose()
                GC.Collect()
              End Sub
            Da habe ich dann unten aus Verzeiflung alles reingeschmissen, was helfen könnte, den Speicher freizumachen, muss aber zugeben, dass ich mir bei den Befehlen nicht sicher bin, ob die so richtig angewandt sind. Funktioniert ja auch nicht. Ich denke, dass dieses Grid einen Großteil Speicher braucht, daher habe ich versucht, es explizit als entbehrlich zu markieren.
            Nichts destotrotz hätte ich prinzipiell aber angenommen, dass ein normales Me.Close() reichen sollte.

            Ich freue mich, dass Ihr da mal drüberschaut ... Danke.

            Dave

            Comment


            • #7
              Hi,

              http://www.galileocomputing.de/openb...tel_04-006.htm

              http://msdn2.microsoft.com/de-de/lib...9e(VS.80).aspx


              Vielleicht bringt's Dich weiter.

              Phil

              Comment

              Working...
              X