Dauerscreenshot - Prozessspeicher

  • VB.NET

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von SoulRaiZor.

    Dauerscreenshot - Prozessspeicher

    Hallo!

    Ich habe einen Code geschrieben, der soll folgendes machen:
    von einem gewissen Bereich des Screens einen Screenshot - und zwar alle 0.5 Sekunden.

    Jetzt ergibt sich folgendes Problem: Wenn ich in Visual Studio 2015 diesen Code ausführe funktioniert er zwar, jedoch steigt der Prozessspeicher mit der Laufzeit immer weiter an.
    Wieso?


    VB.NET-Quellcode

    1. Private Sub tAktualisieren_Tick(sender As Object, e As EventArgs) Handles tAktualisieren.Tick
    2. Dim memoryImage As Bitmap
    3. Dim myGraphics As Graphics = Me.CreateGraphics()
    4. Dim s As Size
    5. s.Height = 961 - 837
    6. s.Width = 884 - 303
    7. memoryImage = New Bitmap(s.Width, s.Height, myGraphics)
    8. Dim memoryGraphics As Graphics = Graphics.FromImage(memoryImage)
    9. memoryGraphics.CopyFromScreen(303, 837, 0, 0, s) 'Start x, Start y , 0, 0, Size Voll definiert mit Start x & y & Size -> Startpunkt suchen und in Size fügen
    10. PictureBox1.Image = memoryImage
    11. End Sub


    Die Variablen sollten außerhalb erstellt werden, aber so erkennt man vielleicht einen Fehler eher.
    Danke für die Mithilfe!
    MfG
    Klaus
    Was also dein Problem ist: Du hast nen Memoryleak weil du die erstellten Bilder nicht wieder ausm RAM holst abe dauernd neue erstellst. Daher brauchst du immer mehr, bis es keinen mehr gibt.

    @ThuCommix schrieb ja schon, wie du das Bild wieder ausm RAM entfernst.
    Danke für die schnelle Antwort.
    Dann habe ich wohl ein grundsätzliches Verständnisproblem.

    Ich dachte das "memoryImage"Bitmap verhält sich wie eine normale Variable und ändert ihren "Wert" einfach mit erneuter Zuweisung.
    Kann ich es mir stattdessen als Array vorstellen?
    Und wo speichert er die Bitmaps hin, bzw. wie kann ich sie abrufen?

    Ein memoryImage.Dispose () nach der PictureBox Zuweisung wird das Problem dann lösen?

    MfG
    Klaus
    Ich würde an deiner Stelle eine globale Variable nehmen und dieser ständig neues zuweisen. Dann ist es auch immer am selben Platz im RAM. Dadurch dass du ja die ganze Zeit eine neue Variable erstellst, wird auch immer mehr Speicher reserviert, und nur weil die Variable gleich heißt, ist es nicht auch die gleiche, da der Name eigentlich nichts aussagt. Wichtig ist die dahinter liegende Adresse im RAM und die ist immer eine neue, aber das auszulesen oder gar mit den Adressen zu arbeiten, übersteigt die Fähigkeiten von Visual Basic...

    Wo es gespeichert wird?
    Random Access Memory = irgendwo

    Das mit dem Dispose könnte Probleme verursachen. Eigentlich ist für sowas der Using-Block da. Einfach mal danach googlen.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ichduersie“ ()

    @ichduersie
    Das stimmt so nicht, eine Variable ist ja nur ein Zeiger auf eine bestimmte Stelle im RAM. Wenn du die Variable änderst, zeigt diese einfach nur auf eine andere Stelle - jedoch wird nicht zwingend der vorherige Wert gelöscht bzw. schon gar nicht überschrieben. Wenn das der einzige Zeiger auf diesen Bereich war und du die Variable veränderst, wird das natürlich von dem Garbage Collector erkannt, aber Bitmap Images müssen manuell verworfen werden, sonst gammeln die bis zum Beenden der Anwendung im RAM.

    @SoulRaiZor
    Erstell eine Variable außerhalb dieser Methode, weise dieser immer die letze Bitmap zu und dispose diese anschließend, nachdem du der Picturebox eine neue gegeben hast. Du musst nur aufpassen, dass du überprüfst, ob die Variable Nothing ist, sonst gibt's ne NullReferenceException.
    Mfg
    Vincent

    Das Problem ist, das Bitmap eine System Resource ist, und solche muss man manuell mit Dispose freigeben wenn man sie nicht mehr braucht. Du solltest also bevor du das neue Bitmap an der PB setzt, das alte disposen.

    VB.NET-Quellcode

    1. ​Private Sub tAktualisieren_Tick(sender As Object, e As EventArgs) Handles tAktualisieren.Tick
    2. Dim memoryImage As Bitmap
    3. Dim myGraphics As Graphics = Me.CreateGraphics()
    4. Dim s As Size
    5. s.Height = 961 - 837
    6. s.Width = 884 - 303
    7. memoryImage = New Bitmap(s.Width, s.Height, myGraphics)
    8. Dim memoryGraphics As Graphics = Graphics.FromImage(memoryImage)
    9. memoryGraphics.CopyFromScreen(303, 837, 0, 0, s) 'Start x, Start y , 0, 0, Size Voll definiert mit Start x & y & Size -> Startpunkt suchen und in Size fügen
    10. If PictureBox1.Image Not Nothing Then
    11. PictureBox1.Image.Dispose()
    12. End If
    13. PictureBox1.Image = memoryImage
    14. End Sub