Speicherverbrauch .NET Anwendung



  • Hallo Leute,

    ich habe eine rel. komplexe .NET Anwendung die viele Ressourcen frist!.
    Ich überwache zyklisch auch den Speicherverbrauch, da zur laufzeit Control (WPF) instanziiert und auch wieder zerstört wurden, dabei prüfe ich ob bei diesen
    Control bei der zerstörung auch wirklich der Destruktor aufgerufen wird, damit ich mir auch sicher sein kann, dass die obejekt vom GC collected wurden! Soviel dazu!

    Bei der zyklischen Speicherüberwachung log ich folgendes:

    Process.GetCurrentProcess().VirtualMemorySize64 //ca. 590MB
    Process.GetCurrentProcess().PrivateMemorySize64 //ca. 200MB
    Process.GetCurrentProcess().WorkingSet64 // ca. 15MB
    

    Im Taskmanager stehen dann wieder gaaaanz anderer werte.. naja aber auf den kann man sich auch nich beziehen!

    Jedenfalls bekomme ich unter Win7 immer das LowMemory MessageBox im bezug auf meine Anwendung, unter WinXP hatte ich nie probleme!

    Achja MAschine: Win7 32Bit mit 4GB Ram, dabei kann Windoows nur 3,25 verwenden (rest andere hardware)! Insgesamt bruahc das system im schnitt 2GB als 67% des physikalischen Speichers!

    Was könne ich jetzt tun? Kann die lowMemory Message best.auch abschalten, aber das das beruhigt mich weniger 😃

    Hoffe Ihr habt mir paar Tipps:) 😃



  • NullBockException schrieb:

    da zur laufzeit Control (WPF) instanziiert und auch wieder zerstört wurden, dabei prüfe ich ob bei diesen
    Control bei der zerstörung auch wirklich der Destruktor aufgerufen wird

    Ein verwaltetes Objekt hat keinen Destruktor. Meinst du den Finalizer oder die Dispose()-Funktion?

    NullBockException schrieb:

    Hoffe Ihr habt mir paar Tipps:) 😃

    Hast du denn die Anwendung mal auf die üblichen Verdächtigen bzgl. WPF und Speicherlecks überprüft? Eine Google-Suche nach "wpf memory leak" ergibt in den ersten Treffern das hier:
    http://blog.jetbrains.com/dotnet/2014/09/04/fighting-common-wpf-memory-leaks-with-dotmemory/
    http://blogs.msdn.com/b/jgoldb/archive/2008/02/04/finding-memory-leaks-in-wpf-based-applications.aspx
    http://ozcode-orchard.azurewebsites.net/top-3-memory-leak-inducing-pitfalls-of-wpf-programming

    Wenn du ein zeitgemäßes VS hast, kannst du den Memory Profiler nehmen, um zu schauen, welche Objekte den Speicher besonders auslasten:
    http://blogs.msdn.com/b/dotnet/archive/2013/04/04/net-memory-allocation-profiling-with-visual-studio-2012.aspx
    Falls du VS 2013 Ultimate hast, verfügst du auch über ein ordentliches Diagnosetool für die Speicherbelegung:
    http://blogs.msdn.com/b/visualstudioalm/archive/2013/06/20/using-visual-studio-2013-to-diagnose-net-memory-issues-in-production.aspx



  • Hast du viele Bilder in deiner Applikation? Das hat mir schon mal die Performance gekillt und braucht extrem viel mehr Speicher, als man annehmen würde (ein 200kb JPEG wird im Speicher dekomprimiert und kann locker 20 MB fressen). Ein paar davon und alles geht den Bach ab.

    Weiterhin: 32-bit Windows? Ich kann mit 8 GB nicht mal mehr richtig im Internet browsen, wie soll da WPF vernünftig laufen 😮



  • /rant/ schrieb:

    Ich kann mit 8 GB nicht mal mehr richtig im Internet browsen, wie soll da WPF vernünftig laufen 😮

    (Das lese ich in letzter Zeit öfter. Was macht ihr alle mit euren Browsern? Ich habe den Firefox mit meistens extrem vielen Tabs laufen, der braucht selten über 1 GB RAM laut Win8-Task-Manager.)



  • Servus Jungs,

    Ja ich meine den Finalizer, "~Foo()" 🙂 Wenn ich dann explizit mal "GC.Collect()" aufrufe, sehe ich auch dass.. objekte freigegeben werden!

    hmm, ja die typischen wpf memory leak ursauchen sind mir teilweiße bekannt, ABER wenn ein object freigeben weird "Aufruf Finalizer" dann geh ich mal davon aus, dass alles ressource des Objeckt freigegeben wurdn!?!? Oder kann ich auf das nich gehn?

    Schonmal eine dickes Merci für die Anworten:)



  • audacia|off schrieb:

    /rant/ schrieb:

    Ich kann mit 8 GB nicht mal mehr richtig im Internet browsen, wie soll da WPF vernünftig laufen 😮

    (Das lese ich in letzter Zeit öfter. Was macht ihr alle mit euren Browsern? Ich habe den Firefox mit meistens extrem vielen Tabs laufen, der braucht selten über 1 GB RAM laut Win8-Task-Manager.)

    Chrome begnügt sich mit mehr, weil es für jeden Tab ein neues Prozess erzeugt. Firefox begnügt sich mit Multitasking, was billiger ist, aber das wird sich bald in Zukunft auch ändern, weil Firefox Googles Weg gehen wird.

    @NBE: Mich würde mal interessieren, weshalb deine Anwendung so viel Speicher braucht.



  • NullBockException schrieb:

    ABER wenn ein object freigeben weird "Aufruf Finalizer" dann geh ich mal davon aus, dass alles ressource des Objeckt freigegeben wurdn!?!? Oder kann ich auf das nich gehn?

    Ohne jetzt wirklich Ahnung von Wpf zu haben:
    Da würde ich mich jetzt nicht drauf verlassen.
    Zum Beispiel könnten Buttons eine Default-Bitmap als Hintergrund haben und diese Bitmap wird nur einmal geladen.
    Wenn der letzte Button verschwindet, könnte die Bitmap ja vorsichtshalber auch weiter im Speicher bleiben, falls wieder ein Button dargestellt wird.
    Ist aber wie gesagt nur ein Beispiel, was vielleicht sein könnte.



  • @IBV: Wenn ich wüsste, weshalb die Anwendung so viel speicher braucht, würde ich net fragen.... was genau die .NET laufzeut bzw, das WPF framework an speicher resviert etc. kann ich ja nich wirklich überwachen!

    Die Awendung ans sich istg rel. "groß" ! Man kann sich vorstellen, dass ich unterschiedliche "Views" Control habe, welche teilweile aus sehr vielen element und etc. bestehen! Diese "Views" überwache ich beim löschen .. ich instanziiere diese on demand "lazy loading" und lösche sie auch wieder bei nich gebraucht, dabei cache ich 10 views im speicher.. aber bei der freigabe eines Views, kann ich eben nich genau beurteilen was da passiert, außer der aufruf vom Finalizer..

    habe eben wenig einflus auf das managed code zeugs:)

    schönen abend euch



  • Naja, deine Frage war, wie man die lowMemory Message abschaltet.
    Wenn du wissen willst, was genau so viel Speicher braucht, dann solltest du einen Profiler benutzen. Der sagt dir das ganz genau.

    L. G.,
    IBV



  • @NullBockException
    Was bitte verstehst du unter "löschen"?
    Wie willst du in .NET 'was löschen?

    WPF ruft weder IDisposable.Dispose noch den Finalizer auf. WPF verlässt sich einfach hübsch auf den GC, der "das Objekt schon irgendwann wegräumen wird".
    Salopp gesagt.
    Für einige von WPF intern verwaltete Sachen wird das anders aussehen, also diverse Bitmap-Caches und was nicht noch alles.

    ich instanziiere diese on demand

    Wieso? Musst du das?
    Bzw. hast du schonmal probiert was passiert wenn du nix "dynamisch instanzierst", sondern einfach die normalen von WPF vorgesehenen Wege gehst?



  • Was bitte verstehst du unter "löschen"?

    Unter löschen meine ich in meinen fall, das Objekt ausm Speicher nehmen freigeben.. !

    Ich verlasse mich auch nich auf irgendwleche IDisposable Implementationen! Nach meiner Erkenntnis, ist ein Objekt "richtig" gelöscht bzw. im Speicher freigeben , wenn der GC Collected hat, und bei dem entsprechenden Objeckt dern Finalizer aufruft!

    Wenn eine WPF Control Bitmap chached, und ich diese WPF Control "lösche" , gehe ich davon aus, dass durch aufruf des Finalizer alles Ressource bzgl. der Object vom Speicher genommen werden.

    Die dynamisch Instanziierung, ist ja nichts ungewöhnliches

    Ich instanziiere ein Control, hänge es an eine ContentControl ,
    hänge es wieder ab, und setze es auf "null" danach GC.Collect Call
    danach wird der Finalizer aufgerufen..

    Ganz normales zeugs eben..



  • Also manuell GC.Collect aufrufen ist Pfusch.
    Und normalerweise unnötig.
    Gibt ein paar Spezielfälle wo man es braucht (weil WPF halt stellenweise etwas doof ist), aber normal eben nicht.

    Ansonsten...
    Ich bin jetzt kein WPF Experte, aber ich meine gelesen zu haben dass WPF sowieso eigene Caches für alle möglichen Resourcen hat. D.h. wenn du ne Bitmap in einen Button reintust, und dann den Button "löscht", dann ist deswegen noch lange nicht die Bitmap "gelöscht". Also zumindest nicht die eigentlichen Bitmap Daten.



  • Also manuell GC.Collect aufrufen ist Pfusch.

    klar is das pfusch, aber zu debug- überwachsungz/test wecken nutz ich das,

    um eben typische WPF memory leak ursachen zu finden...

    im gewöhnlichen umfeld lass ich den GV selbst seine sache machen!

    Die eigentliche bzw. wichtige frage ist: wie wpf speicher managed, und cached (bswp. bitmap files) , welche konstrukte speocher fressen!

    und das wichtigste :

    ob ich davon ausgehen kann, dass ein objeckt auch korrekt vom speicher freigeben ist, wenn der Finalizer aufgerufen wurde...

    🙂



  • Du hast nicht verstanden, dein ClientObjekte (.NET Objekte) benutzen HintergrundResourcen die ausserhalb von GC Heap liegen, und nie bereinigt werden können, weil du das Dispose-Pattern nicht anwendest! Wie kannst du von ein Objekt das schon zerstört ist, Dispose aufrufen?



  • @Zeus
    Wo gibt's bei WPF was zu disposen? Das ist ja genau eine der Schwächen (oder Stärken, je nachdem wie man es sieht), dass WPF "Dispose-frei" ist.

    Und weil du das Dispose-Pattern ansprichst: das ist mMn. der grösste Dreck den MS in letzter Zeit (softwaredesignmässig) angerichtet hat.
    Ich hab' noch nirgends Klassen gebraucht die gleichzeitig unmanaged Resourcen und "disposable" Resourcen benötigen.
    (Damit kein Misverständnis aufkommt: IDisposable ist genial. Nur void Dispose(bool disposing) ist Schwachsinn.)



  • Hmpf WinForms und WPF verwechselt 😞



  • hustbaer schrieb:

    Ich hab' noch nirgends Klassen gebraucht die gleichzeitig unmanaged Resourcen und "disposable" Resourcen benötigen.

    Das IDisposable ist ja auch für dich im nächsten Moment wenn du z.B. die Wrapper-Klasse bzw. die Klasse die auf die unmanaged Resourcen zugreift notwendig. - Schließlich gibst du die unmanaged Sachen dann mit Dispose() frei.



  • @inflames2k
    Ich verstehe deinen ersten Satz nicht.
    Was willst du mir damit sagen?
    Ja, IDisposable implementiert man dauernd irgendwo. Ich hab auch nie was anderes behauptet.

    Nur das Dispose-Pattern macht keinen Sinn.
    Falls du anderer Meinung bist, dann schreib mir bitte so dass man es auch verstehen kann warum. Also z.B. in was für einem (konkreten) Fall man es brauchen würde.


Anmelden zum Antworten