Arbeitsspeicher - Problem oder nicht?

  • Hallo zusammen,

    ich möchte mal in diesem Tread ein wenig über den Arbeitsspeicher eines PC's/Laptops zusprechen kommen.

    Wie ich derzeit feststellen muss, arbeitet mein Programm (Chatbot Susi) auf einen virtuellen Server mit aktuell 532 MB Verbrauch. Ich weiß jedoch auch das es mal nur um die 30 oder 40 MB waren.

    Meine Frage daher lautet, was kann in einen Script zu so einer hohen Auslastung an Speicher führen?

    Chatbot Susi aktuell 1303 Codezeilen, mit allen Includes auf 9400 Codezeilen.

    Über generelle Tipps und ggf. Tricks zur Reduzierung von Speicher wäre ich sehr verbunden.

    MfG Freeman

    • Offizieller Beitrag

    Dein Speicherverbrauch kann sich durchaus auf diese Größe aufblasen.
    Ohne Code wird dir da aber keiner helfen können.

  • Hallo,

    es geht mir nicht um Hilfe im Sinne von schaut auf den Code, sondern um allgemein, so das jeder Neuling sich hier einlesen kann.

    Ich frage mal ein wenig genauer:

    Ich verwende zum Beispiel in einer Funktion 3 if-abfragen, die alle 3 fast das selbe machen. Wenn ich diese umschreibe und reduziere, kann dies helfen?
    Viele Variablen sind bei mir nicht declariert, sollte man dies machen?
    Sollte man sein Script allgemein auf unnötige Funktionen, Werte, Abfragen überprüfen?

    Ich habe mehrere Funktionen welche immer wieder einen neuen Wert haben, funktion 1 = $meindata, funktion 2 = $meindata2 usw.
    Diese werden nacheinander aufgerufen, bzw. in verschieden Abständen, kann ich diese $meindata für alles verwenden? (darauf hin spare ich ca. 30 Codezeilen wenn es gehen sollte)

  • Hi,

    Zitat

    Ich verwende zum Beispiel in einer Funktion 3 if-abfragen, die alle 3 fast das selbe machen. Wenn ich diese umschreibe und reduziere, kann dies helfen?


    Nein, der eigentliche Code im Speicher nimmt nur ein absolutes Minimum an Platz ein.
    Überleg mal, mit welchen Zahlen du arbeitest! 1 MB ist ein Megabyte, das sind tausend Kilobyte, hundert MB daher hunderttausend Kilobyte!
    Da "hilft" es nicht, indem man einige Zeilen Code oder einige Variablen einspart^^
    Relativ viel Speicher wird durch Funktionen belegt, die intern Kopien von Daten anlegen, z.B. einige der Stringfunktionen. Weiterhin "verballern" große Bilder auch häufig viel Platz.

    Lass dein Programm mal langsam laufen (Stopfunktionen einbauen), und schau mal nach dem Speicherverbrauch bei bestimmten Funktionen. Einige der AutoIt-Funktionen hatten in der Vergangenheit Memory-Leaks, d.h. bei mehrmaligem Aufrufen wurde immer wieder neu Speicher reserviert. Eine aktuelle AutoIt-Version könnte da Abhilfe schaffen!

    Wird der Speicher kontinuierlich gefüllt, z.B. in jeder Sekunde 2KB mehr?
    Dann such die Funktion, die das verursacht.

  • Selbst extrem aufwendige Scripte verbrauchen normalerweise kaum RAM (weniger als 30MB). Ich würde vermuten, dass du enorme Datenmengen Zwischenspeicherst, z.B. durch Dateitransfers. Filerad liest z.B. die komplette Datei in den Speicher. Soll dein Chatbot also auch zur Übertragung größerer Dateien dienen empfiehlt es sich diese Byteweise in ein größentechnisch begrenztes Array einzulesen (Lese Cache), anstatt komplett. Beispiele dazu findest du wenn ich mich recht erinnere unter anderem in einer der crypt Funktionen.

    Andere Ursachen könnten natürlich auch Schleifen sein, die in jedem Durchgang den Inhalt einer Variable oder eines Arrays permanent kopieren. Aber wie schon gesagt wurde ist es ohne Code unmöglich dir hier die Ursache zu nennen.

  • Ich besitze die aktuelle Version von autoIT, der Speicher steigt nach und nach.

    Derzeitig läuft das Prog 10 Tage und ist im Speicher bei 323MB eine neuere Version von dem aktuellen Coder frist derzeitig 545MB.

    Von einer Stopfunktionen habe ich noch nie was gehört, geschweige denn gelesen.

    Das Script liest inis und schreibt auch welche. (Daten)

    Ich habe mal den Code angehangen von einer älteren Version, dieser sollte aber ausreichen um mal zu schauen.

    Der Code ansich hat sich kaum oder nur wenig geändert.

    Edit: Ich hoffe auch durch diese Diskussion anderen helfen zu können, denn zu einem solchen Thema hat mir die Sufu keine Ergebnisse geliefert.

  • Mit Stopfunktion meine ich, den Speicherfresser "auszustoppen".
    Wenn kontinuierlich mehr RAM belegt wird, dann kommt das von einer der verwendeten Funktionen. Um diese zu finden, hält man das Script per "Stop"-Funktion (die musst du dir einfach schreiben, ggf nur ne Msgbox) an den relevanten Stellen einfach an.
    Wenn zwischen den "Stops" (also zwischen den Funktionsaufrufen) der Speicher sich unvorhergesehen verändert, dann grenzt man weiter ein....uswusf

  • [autoit]


    ; DeTokenise by myAut2Exe >The Open Source AutoIT/AutoHotKey script decompiler< 2.9 build(138)

    [/autoit]

    Öhm ja. ?(


    Davon mal ab würde ich das Speicherproblem bei den unzähligen winhttp Aufrufen vermuten. Ich gehe davon aus, dass etliche Handles nicht geschlossen werden und sich der Speicherverbrauch dadurch mit der Zeit summiert, hab das aufgrund des Umfanges jetzt aber auch nur überflogen und könnte da falsch liegen. Testen kann mans ohne die unzähligen Includes die dein Decompiler unterschlagen hat und entsprechende Testzugangsdaten ja ohnehin nicht. Es fehlen im übrigen auch Funktionen z.B. XSKINBUTTON() welche in irgendeinerweise mit der Funktion _go() zusammenhängen dürfte. Wie dem auch sei, da du offensichtlich nicht der Autor des Scriptes bist und den originalen Quellcode nicht besitzt macht weiterer Support hier denke ich kaum Sinn.

  • Danke Andy, werde es beherzigen.

    So und nun zum eigentlichen Teil:

    Gibt es allgemeine Tipps zum Thema Arbeitsspeicher? Was kann man machen damit man nicht in meine Lage kommt?

  • Ja. Sauber programmieren und jede Resource wieder freigegen, wenn sie nicht mehr gebraucht wird.


    Säubern, daran arbeite ich gerade, jedoch wie gebe ich Resouren wieder frei ?(

  • Vielleicht hilft dir diese Funktion weiter:

    [autoit]

    Func _ReduceMemory($i_PID = -1)

    If $i_PID <> -1 Then
    Local $ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $i_PID)
    Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', $ai_Handle[0])
    DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $ai_Handle[0])
    Else
    Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', -1)
    EndIf

    Return $ai_Return[0]
    EndFunc;==> _ReduceMemory()

    [/autoit]

    ;)

    Mfg

    There's a joke that C has the speed and efficieny of assembly language combined with readability of....assembly language. In other words, it's just a glorified assembly language. - Teh Interwebz

    C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, you blow off your whole leg. - Bjarne Stroustrup
    Genie zu sein, bedeutet für mich, alles zu tun, was ich will. - Klaus Kinski

  • Ich glaube nicht, dass EmptyWorkingSet da großartig hilft.
    Entweder das Programm ist sauber und dann kommt es auch ohne klar, oder es ist nicht sauber, dann verzögert EmptyWorkingSet nur die Probleme, aber behebt sie nicht.
    Es nützt nicht viel, nur die Symptome zu bekämpfen, man muss die Ursache beheben.

    Wie man eine Resource freigibt, hängt von der Art ab. Dateien und FileSearches schließt man mit FileClose, manche WinAPI-Handles schließt man mit _WinAPI_DeleteObject.
    Andere Resourcen werden vielleicht auch von eigenen Dlls geladen und müssen durch diese auch wieder freigegeben werden.
    Man sollte nach Möglichkeit jede Resource ab dem Zeitpunkt wieder freigeben, ab dem man sie nicht mehr braucht.