Ressourcen Killer / Speicher freigeben

  • VB.NET

Es gibt 1 Antwort in diesem Thema. Der letzte Beitrag () ist von Mad Andy.

    Ressourcen Killer / Speicher freigeben

    Hallo,

    eins meiner Programme verursacht nach recht kurzer Laufzeit (ca 12h) eine CPU Auslastung von (permanent) 99% und belegt "Quasi"
    den ganzen Arbeitsspeicher (auf meinem Server immerhin 512MB, bzw was eben noch frei ist (normalerweise ca 200 MB genutzt))

    Das ist nicht nur "unschön" sondern wirkt sich natürlich auch wahnsinnig auf die Geschwindigkeit und Temperatur der CPU aus (68° statt 55)

    Den ganzen Quelltext zu posten wäre nun irrsinnig, aber Grundlegene Strukturen verwende ich immer wieder, und wollte mal "wissen" ob der
    Speicher danach wieder freigegeben wird, oder ob das alles als "leiche" rumschwirrt...

    1.) In einer LV zeige ich eine "recht ausführliche" Log an, die auch als TXT gespeichert wird. Wäre es ratsam das LV ab und zu zu "leeren" zwecks Speicherbelastung? (die log.txt hingegen hat nach einem Tag ca 800 KB - 1500 KB)

    2.)
    z.B so ein Konstrukt taucht öfter auf

    VB.NET-Quellcode

    1. For Each Match In LeftMatches
    2. 'get UID
    3. Dim UIDMatch As RegEx.Match


    Hier wir ja jedesmal speicher für das UIDMatch-Objekt erstellt - wird dieser beim nächsten "For-"Durchgang wieder freigegeben, erst mit ende der funktion, oder GAR nicht ?!

    Dass das Prog sehr Speicherlastig ist, ist klar, da es um die Synchronisation 2er ICS-Files geht, die erst komplett eingelesen und dann per regex in mehrer Regex.MatchCollections aufgeteilt werden...

    Habe bereits ein Topic dazu hier gefunden, allerdings wollte ich das nicht ausgraben und es führte auch zu keiner Lösung...


    Zur CPU-Auslatung:
    Da in regelmäßigen Intervallen "synchronisiert" werden soll, verwende ich folgendes Konstrukt (Je nach gespeichertem Wert in der Ini)

    VB.NET-Quellcode

    1. Public seconds As Integer
    2. Public totalseconds As Integer
    3. Public minutes As Integer
    4. Private Sub sync_timer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles sync_timer.Tick
    5. seconds += 1
    6. totalseconds += 1
    7. If seconds = 59 Then
    8. minutes += 1
    9. seconds = 0
    10. End If
    11. If minutes >= ini.GetINIInt("config.ini", "root", "intervall", 30) Then
    12. functions.SyncAllTasks()
    13. minutes = 0
    14. seconds = 0
    15. totalseconds = 0
    16. ProgressBar1.Value = 0
    17. End If
    18. 'progressbar
    19. Dim value As Integer = totalseconds / (ini.GetINIInt("config.ini", "root", "intervall", 30) * 60) * 100
    20. If value > 100 Then
    21. value = 100
    22. End If
    23. ProgressBar1.Value = value
    24. End Sub


    okay, anmerkung: Es wäre wohl wesentlich entlastender die Config-Var nicht jedesmal auszulesen, sondern onload und dann global zu speichern, oder ?
    Wie könnte ich einen solchen "Teitgeber" sparsamer gestalten?! (Timer tick = 1000)

    grüße,
    dognose
    Hi!

    Ich würde den Wert aus der ini nur beim Starten auslesen und in Sekunden umrechnen, damit du beim Timer wirklich nurnoch Sekunden gegen Sekunden abgleichen musst. Das sollte aber nicht wirklich viel ausmachen.

    VB.NET-Quellcode

    1. For Each Match In LeftMatches
    2. 'get UID
    3. Dim UIDMatch As RegEx.Match
    4. ...
    5. Next Match
    UIDMatch ist (vermutlich) nur eine Referenz, der richtige Speicher wird erst bei der Zuweisung (UIDMatch = ...) belegt. Die Variable (ein Pointer, Long Integer) wird nach jedem Durchlauf gelöscht, der richtige Speicher aber wahrscheinlich erst, wenn der Garbage Colelctor rüber fährt. Du kannst auch UIDMatch außerhalb der Schleife deklatieren, wodurch der Pointer nicht immer neu angelegt werden muss, das wird aber kaum etwas ausmachen...


    Wenn du nach dem Abarbeiten (nach einer Synchronisation) noch immer extreme Auslastungen hast, kann das eigentlich nur die 2 Gründe haben:
    1. Du hast irgendwo Leichen (ungenutzte Referenzen) rumliegen, was durch den Garbage Collector eig. ungewöhnlich ist, wenn du nur managed Code (keine C++-DLLs) verwendest.
    2. Der Garbage Collector kommt nicht mit, was ein durchaus bekanntes Problem ist.

    Die beste Möglichkeit um sicherzustellen, dass nach ablaufen alles gelöscht wird, was keine Referenz hat, ist den Garbage Collector collecten zu lassen: System.GC.Collect

    Um dem Garbage Collector ein wenig Arbeit abzunehmen (wenn du .net 2.0 verwendest), ist es Using zu verwenden, da das nach dem End Using automatisch den Speicher der Variable löscht. Google: Using Statement vb.net
    So weit ich weiß, kannst du Dispose auch händisch aufrufen, was dann auch dem Garbage Collector die Arbeit abnimmt und den Speicher frei gibt.