Speicherproblem - wie Speicher wieder freigeben

  • Hallo ich habe folgendes Problem wo ich nicht weiterkomme.
    Ich habe eine Gui mit einen Grid (im Prinzip 3) aber wenn ich das Grid aktualisiere
    in dem Fall wird eine Textdatei (Ini) eingelesen nimmt die Arbeitsspeichernutzung um ~1MB zu .
    wenn ich den Vorgang so oft wiederhole das ich in den 20-25 MB Bereich komme, dann bekomme ich Fehler in der Darstellung/ Nutzung.
    Es scheint das ihm nicht mehr als 25MB zugestanden werden, muss auch nicht erstens ruft das Programm keiner sooft hintereinander auf
    und die Ursache ist ja die, das irgendwie der Speicher nicht freigegeben wird. Ich denke das kann man lösen. :)

    Hoffentlich auch ohne Script da ich es für mich und meine Arbeitskollegen gescriptet habe und halt evtl. Interna enthält,
    will ich erst bereitstellen wenn alles läuft und dahingehend von mir noch intensiver durchgehen wurde.

    Genutzt wird übrigens LV_Format_include.au3 weitere includes:

    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <ListViewConstants.au3>
    #include <StaticConstants.au3>
    #include <TabConstants.au3>
    #include <WindowsConstants.au3>
    #include <GuiListBox.au3>
    #include <GuiListView.au3>
    #include <File.au3>
    #include <array.au3>
    #include <ComboConstants.au3> ;für Combobox disablen
    #include <C:\Autoit_SVN\UDF\MS-SQL.au3>


    Die 3 Grids sind vom Aufbau gleich Anzahl Spalten usw. und werden so zusammengefasst:

    [autoit]

    Local $aHWnd_Tab1[3] = [$hListView_DSN_DB_Tab1,$hListView_System_Tab1,$hListView_User_Tab1]

    [/autoit]

    So lese ich die Datei ein und dann 2 ineinander verschachtelte Case Anweisungen

    [autoit]

    Func _Fill_Server_DSN_Listbox($DB_Filter) ; temporäre Ini Datei für DB Grid auslesen
    _Disable_Tab1(0)
    _GUICtrlListView_DeleteAllItems(GUICtrlGetHandle($ListView_DSN_DB_Tab1))
    $DSN_Create = GUICtrlRead($Combo_DSN_Name_Tab1)
    ;~ $cnt_nr = 0
    $cnt_dbserver=IniReadSectionNames(@TempDir & "\tmp_server.ini")

    [/autoit][autoit][/autoit][autoit]

    For $i_cnt = 1 to UBound($cnt_dbserver,1) -1
    $cnt_dbname=IniReadSection(@TempDir & "\tmp_server.ini",$cnt_dbserver[$i_cnt])

    [/autoit][autoit][/autoit][autoit]

    For $j_cnt = 1 to UBound($cnt_dbname,1) -1

    [/autoit][autoit][/autoit][autoit]

    Select
    Case $DSN_Create = "DSN = [Datenbank]" ;Or $DSN_Create = ''
    $DSN_Name = $cnt_dbname[$j_cnt][0]
    Case $DSN_Create = "DSN = [Datenbank]-[Server]"
    .....
    Endselect
    Weiter unten noch einmal case für den SuchFilter
    Select
    Case $DB_Filter = "Alle Datenbanken" ;Or $DB_Filter = ""
    _GUICtrlListView_AddOrIns_Item($hListView_DSN_DB_Tab1, $DSN_Name & "|" & $cnt_dbserver[$i_cnt] & "|" & $cnt_dbname[$j_cnt][0] & "|" & $cnt_dbname[$j_cnt][1])
    Case $DB_Filter = "DB* (ASP Kunden)"
    If StringLeft($cnt_dbname[$j_cnt][0],2) = "DB" Then _
    _GUICtrlListView_AddOrIns_Item($hListView_DSN_DB_Tab1, $DSN_Name & "|" & $cnt_dbserver[$i_cnt] & "|" & $cnt_dbname[$j_cnt][0] & "|" & $cnt_dbname[$j_cnt][1])
    ......
    EndSelect
    Next
    Next
    _Mark_DSN($ListView_DSN_DB_Tab1)
    endfunc()

    [/autoit][autoit][/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func _Mark_DSN($Target_Listbox) ; Non Latin Collations markieren
    If $Target_Listbox = $ListView_DSN_DB_Tab1 Then
    $Mark_Col = 3
    Else
    $Mark_Col = 4
    EndIf
    For $i = 0 To _GUICtrlListView_GetItemCount($Target_Listbox) -1
    $Test_Col = _GUICtrlListView_GetItemText($Target_Listbox, $i, $Mark_Col)
    If Not StringInStr($Test_Col,'LATIN') And $Test_Col <> '' And $Test_Col <> "SQL2000" And $Test_Col <> "keine Beschreibung" Then
    _GUICtrlListView_FormattingCell($Target_Listbox, $i, $Mark_Col, 0x00FFFF, -1, -1, 300);, 'Times New Roman')
    EndIf
    Next
    For $i = 0 To _GUICtrlListView_GetItemCount($Target_Listbox) -1
    If _GUICtrlListView_GetItemText($Target_Listbox, $i, 4) = 'Offline' Then
    _GUICtrlListView_FormattingCell($Target_Listbox, $i, 4, 0xff0000, -1, -1, 300);, 'Times New Roman')
    EndIf
    Next
    _Disable_Tab1(1)
    EndFunc

    [/autoit]

    Mit _Disable_Tab1(0/1) werden die Buttons kurzzeitig deaktiviert.

    Was mach ich falsch?

    Gruß Dietmar

    Achtung Anfänger! :whistling:

    Betrachten des Quellcodes auf eigene Gefahr, bei Übelkeit,Erbrechen,Kopfschmerzen übernehme ich keine Haftung. 8o

    Einmal editiert, zuletzt von Dietmar (14. November 2010 um 20:04)

  • Schade keiner ne Idee, habe dann ma ne andere Frage
    zu Drag n Drop zwischen Listboxen habe ich bereits etwas gefunden, was mir allerdings noch fehlt,
    ist etwas um die gesamte Auswahl der Listbox zu markieren.

    [autoit]

    Case $Button_SelectAll_Tab1
    Send("{CTRLDOWN}")
    for $i = 1 to 100
    _GUICtrlListView_ClickItem($hListView_DSN_DB_Tab1,$i)
    Next
    Send("{CTRLUP}")

    [/autoit]

    Das kann es doch wohl nicht sein, das muss doch "einfacher" gehen. :D

    Ohne CTRL UP/DOWN bleibt ja immer nur einer markiert und ich will ja alle :(

    Gruß Dietmar

    Achtung Anfänger! :whistling:

    Betrachten des Quellcodes auf eigene Gefahr, bei Übelkeit,Erbrechen,Kopfschmerzen übernehme ich keine Haftung. 8o

  • Guten Morgen,

    testen kann man das schon:

    Spoiler anzeigen
    [autoit]

    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <ListViewConstants.au3>
    #include <StaticConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Dim $File = @ProgramFilesDir & "\AutoIt3\Include\StructureConstants.au3"
    Dim $Round = 0

    [/autoit] [autoit][/autoit] [autoit]

    Opt("MustDeclareVars", 1)
    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    Dim $hGUI = GUICreate("ListView", 800, 600)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_GUI_Closed")
    Dim $idLsV = GUICtrlCreateListView("StructureConstants.au3", 20, 20 ,760, 400)
    GUICtrlSendMsg($idLsV, $LVM_SETCOLUMNWIDTH, 0, $LVSCW_AUTOSIZE_USEHEADER)
    GUICtrlSetFont(-1, 9, Default, Default, "Courier New")
    Dim $idBtn = GUICtrlCreateButton("Neu einlesen", 20, 440, 100, 20)
    GUICtrlSetOnEvent(-1, "_Btn_Clicked")
    Dim $idEdt = GUICtrlCreateEdit("", 20, 480, 760, 100, $ES_READONLY + $ES_AUTOVSCROLL)
    GUICtrlSetData(-1, "Lauf 0" & @TAB & "Zeilen = 00000" & @TAB & "Belegter Speicher = " &_GetMem() & @CRLF)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While True
    Sleep(1000)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _GUI_Closed()
    GUIDelete()
    Exit
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Btn_Clicked()
    GUISetState(@SW_LOCK)
    GUICtrlSendMsg($idLsV, $LVM_DELETEALLITEMS, 0, 0)
    Local $hFile = FileOpen($File)
    If $hFile = -1 Or @error Then Return
    Local $Record = FileReadLine($hFile)
    While Not @error
    GUICtrlCreateListViewItem($Record, $idLsV)
    $Record = FileReadLine($hFile)
    WEnd
    FileClose($hFile)
    GUICtrlSendMsg($idLsV, $LVM_SETCOLUMNWIDTH, 0, $LVSCW_AUTOSIZE)
    Local $Items = StringFormat("%05d", GUICtrlSendMsg($idLsV, $LVM_GETITEMCOUNT, 0, 0))
    $Round += 1
    GUICtrlSetData($idEdt, "Lauf " & $Round & @TAB & "Zeilen = " & $Items & @TAB & "Belegter Speicher = " &_GetMem() & @CRLF, 1)
    GUISetState(@SW_UNLOCK)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetMem()
    Local Static $LastMem = -1
    Local $Diff = 0
    Local $aStats = ProcessGetStats()
    If $LastMem <> -1 Then $Diff = $aStats[0] - $LastMem
    $LastMem = $aStats[0]
    Return StringFormat("%09d (%+010d)", $aStats[0], $Diff)
    EndFunc

    [/autoit]


    Ich sehe allerdings keinen schlüssigen Zusammenhang, an dem man den Speichermehrverbrauch festmachen könnte.

  • ... na ja, es war ja zu vermuten, dass sich im großen Forum etwas findet: hier.

    Und es geht damit sehr einfach:

    Spoiler anzeigen
    [autoit]

    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <ListViewConstants.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Dim $File = @ProgramFilesDir & "\AutoIt3\Include\StructureConstants.au3"
    Dim $Round = 0

    [/autoit] [autoit][/autoit] [autoit]

    Opt("MustDeclareVars", 1)
    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    Dim $hGUI = GUICreate("ListView", 800, 600)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_GUI_Closed")
    Dim $idLsV = GUICtrlCreateListView("StructureConstants.au3", 20, 20, 760, 400)
    GUICtrlSendMsg($idLsV, $LVM_SETCOLUMNWIDTH, 0, $LVSCW_AUTOSIZE_USEHEADER)
    GUICtrlSetFont(-1, 9, Default, Default, "Courier New")
    Dim $idBtn1 = GUICtrlCreateButton("Neu einlesen", 20, 440, 100, 20)
    GUICtrlSetOnEvent(-1, "_Btn1_Clicked")
    Dim $idBtn2 = GUICtrlCreateButton("Speicher freigeben", 140, 440, 100, 20)
    GUICtrlSetOnEvent(-1, "_Btn2_Clicked")
    Dim $idEdt = GUICtrlCreateEdit("", 20, 480, 760, 100, $ES_READONLY + $ES_AUTOVSCROLL + $WS_VSCROLL)
    GUICtrlSetFont(-1, 9, Default, Default, "Courier New")
    GUICtrlSetBkColor(-1, 0xFFFFFF)
    GUICtrlSetData(-1, "Lauf 0" & @TAB & "Zeilen = 00000" & @TAB & "Belegter Speicher = " & _GetMem() & @CRLF)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While True
    Sleep(1000)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _GUI_Closed()
    GUIDelete()
    Exit
    EndFunc ;==>_GUI_Closed

    [/autoit] [autoit][/autoit] [autoit]

    Func _Btn1_Clicked()
    GUISetState(@SW_LOCK)
    GUICtrlSendMsg($idLsV, $LVM_DELETEALLITEMS, 0, 0)
    Local $hFile = FileOpen($File)
    If $hFile = -1 Or @error Then Return
    Local $Record = FileReadLine($hFile)
    While Not @error
    GUICtrlCreateListViewItem($Record, $idLsV)
    $Record = FileReadLine($hFile)
    WEnd
    FileClose($hFile)
    GUICtrlSendMsg($idLsV, $LVM_SETCOLUMNWIDTH, 0, $LVSCW_AUTOSIZE)
    Local $Items = StringFormat("%05d", GUICtrlSendMsg($idLsV, $LVM_GETITEMCOUNT, 0, 0))
    $Round += 1
    GUICtrlSetData($idEdt, "Lauf " & $Round & @TAB & "Zeilen = " & $Items & @TAB & "Belegter Speicher = " & _GetMem() & @CRLF, 1)
    GUISetState(@SW_UNLOCK)
    EndFunc ;==>_Btn1_Clicked

    [/autoit] [autoit][/autoit] [autoit]

    Func _Btn2_Clicked()
    _ReduceMem()
    Local $Items = StringFormat("%05d", GUICtrlSendMsg($idLsV, $LVM_GETITEMCOUNT, 0, 0))
    GUICtrlSetData($idEdt, "Lauf " & $Round & @TAB & "Zeilen = " & $Items & @TAB & "Belegter Speicher = " & _GetMem() & @TAB & "(_ReduceMem)" & @CRLF, 1)
    EndFunc ;==>_Btn2_Clicked

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetMem()
    Local Static $LastMem = -1
    Local $Diff = 0
    Local $aStats = ProcessGetStats()
    If $LastMem <> -1 Then $Diff = $aStats[0] - $LastMem
    $LastMem = $aStats[0]
    Return StringFormat("%09d (%+010d)", $aStats[0], $Diff)
    EndFunc ;==>_GetMem

    [/autoit] [autoit][/autoit] [autoit]

    Func _ReduceMem()
    Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', -1)
    Return SetError(@error, @extended, $ai_Return[0])
    EndFunc ;==>_ReduceMem

    [/autoit]


    !!! Wegen Risiken und Nebenwirkungen lesen Sie bitte die Packungsbeilage und fragen Sie Ihren Arzt oder Apotheker !!!

  • [autoit]

    Func _ReduceMem()
    Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', -1)
    Return SetError(@error, @extended, $ai_Return[0])
    EndFunc ;==>_ReduceMem

    [/autoit][autoit][/autoit][autoit][/autoit]

    Unglaublich, nun bleibe ich ~ konstant unter 7MB schaukelt sich nicht mehr auf > 20MB hoch
    Das Problem ist aber leider geblieben, ich kann es ziemlich genau 10x aufrufen dann klappen die Komboboxen nicht mehr auf :(

    [autoit]

    _GUICtrlListView_SetItemSelected($hListview, -1, True)

    [/autoit]


    Tuts leider auch nicht, ich werde mal das Script etwas säubern und dann hier irgendwo anpinnen.
    Mal gespannt was da noch für Sachen hochkommen, man evtl. besser machen kann.

    Gruß Dietmar

    Achtung Anfänger! :whistling:

    Betrachten des Quellcodes auf eigene Gefahr, bei Übelkeit,Erbrechen,Kopfschmerzen übernehme ich keine Haftung. 8o