Arbeitsspeicherauslastung zu Hoch

  • VB.NET

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von Bartosz.

    @Pixxxas Das nennt sich Debuggen.
    Führe Dein Programm schrittweise aus und verfolge die Anzeige im Studio.
    Debuggen, Fehler finden und beseitigen
    Ansonsten füge nach jedem Befehl einen Befehl ein, der den Speicher anzeigt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Beim Prozessspeicher werden diese 2,2GB angezeigt? Ist wie beim Browser mit 30 geöffneten Fenstern. Unten als Screenshots ein Vergleich mit meinem jetzigen Programm in vb.NET mit WPF, welches aber noch lange nicht fertig ist – fast 80 Tausend Objekte, fast 4MB Heapspeicher- und insgesammt ca. 80MB Arbeitsspeicherbedarf; am Ende, wenn es fertig wird, wird es bestimmt noch mehr sein, weil noch diverse Bild- und Audiodateien dazukommen werden, aber bestimmt keine 2GB – so einen hohen Bedarf habe ich mal versuchsweise unter WinForms mit Anlegen von 1GB-Variablen als Array simuliert und getestet, um zu schauen, wie weit es geht und da war dann irgendwo bei 3,7 oder 3,8GB Schluss, weil bei 4GB die derzeitige physische Grenze erreicht wird (32-Bit Zahl ohne Vorzeichen). Ich habe es jetzt nochmal spaßhalber zum Leben erweckt und im Anhang ein zusammengesetztes Bild hochgeladen, wo es stufenweise bis zur dieser Grenze getrieben wird – danach, ab ca. 3,7GB, ist dann Feierabend. Die Variablen werden auch mit konkreten Werten gefüllt, damit unser Freund denkt, das sei real. Den tatsächlich zur Verfügung stehenden Speicher zur Laufzeit kann man sich im vb.NET als Zahl auch ausgeben lassen. Übrigens, auf diesem PC mit Win10 mangelt es nicht an Speicher - es sind 16GB verbaut. Wer über diese magische Grenze hinausgehen will, muss das über „x64 Ziel-CPU ohne 32-Bit-Bevorzugung” machen, aber wenn so viel RAM in einer Applikation ohne einen besonderen Grund benötigt wird, dann ist beim Entwurf des eigenen Konzepts offensichtlich etwas mächtig in die Hose gegangen.

    Ob man das im Debugger so aufschlüsseln kann, dass das exakt sichtbar wird, wo genau was und wieviel an Speicher in Anspruch nimmt, weiß ich nicht – notfalls muss man das mit auskommentieren und Breakpoints immer weiter einkreisen, bis man sich dann sicher ist, dass man es erwischt hat, weil es immer durch unser künstliches Umschalten reproduzierbar ist. Meistens ist die Misere aber ein Verbund aus vielen Speicherreservierungen, die zu so einem Desaster führen – oft werden Programmbeispiele von sogenannten „Möchtegerne-Gurus” aus dem Netz 1:1 und ohne weiter nachzudenken übernommen, wo dann Objekte, Variablen, Felder etc. immer wieder mit New() in Prozeduren/Funktionen und mit Mausklicks erzeugt werden, statt sie nur einmal (sic!) vorher zu erzeugen und dann durch Zuweisung immer wieder zu verwenden – fast alle machen den Blödsinn nach und der Müllsammler (=GarbageCollector) ist auch nur ein „Mensch” und kann den durch den Codeschreiber oder -kopierer verursachten Mist dann auch nicht immer wegzaubern.

    VB.NET-Quellcode

    1. Public RAM_Max As Integer = 1024 * 1024 * 1000 '1000
    2. Public RAM_Array1(RAM_Max) As Byte
    3. Public RAM_Array2(RAM_Max) As Byte
    4. Public RAM_Array3(RAM_Max) As Byte
    5. Public RAM_Max4 As Integer = 1024 * 1024 * 300 '1000
    6. Public RAM_Array4(RAM_Max4) As Byte
    7. Public Sub RAM_Test()
    8. Dim z As Integer = 0
    9. For x As Integer = 0 To RAM_Max
    10. RAM_Array1(x) = CByte(z)
    11. RAM_Array2(x) = CByte(z)
    12. RAM_Array3(x) = CByte(z)
    13. z = z + 1
    14. If z > 255 Then z = 0
    15. Next
    16. For x As Integer = 0 To RAM_Max4
    17. RAM_Array4(x) = CByte(z)
    18. z = z + 1
    19. If z > 255 Then z = 0
    20. Next
    21. End Sub
    Bilder
    • Speicherauslastung_1_Test100MB-3.7GB.png

      126,08 kB, 1.294×1.226, 53 mal angesehen
    Das gleichzeitige Erscheinen von Dummheit und Unmündigkeit nach Immanuel Kant ist eines der schlimmsten Dinge, die einem Homo sapiens in geistiger Hinsicht widerfahren können, hat manchmal aber auch durchaus seine Vorteile.

    Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von „Gregor Jasinski“ ()

    Was du suchst, ist ein Memory Profiler - den bringt VS übrigens mit.
    In dem siehst du rechts ganz genau wo und für welche Objekte Speicher allokiert wird - und auch wo er leckt.

    In managed Sprachen wie die .Net-Familie sind das oft Objekte, die man irgendwo füllt, aber die Referenz drauf nicht löscht. Dann kann der Garbage Collector nicht aufräumen und dann kommt sowas zustande.

    In grafisch-intensiven Applikationen sind das dann natürlich auch Bilder und Styles, die so viel in Anspruch nehmen.

    Wenn du dein Programm im Debugger startest, zeigt dir VS aber auch deutlich mehr an, als dein Prozess selber benötigt, weil der Debugger und alle weiteren Tools mit deinem Programm in einem Speicherbereich arbeiten - muss ja, sonst funktionieren sie nicht.

    Dieser Link sollte dir auf die Sprünge helfen: learn.microsoft.com/en-us/visu…t-debugging2?view=vs-2022
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems
    Meine Privatwebseite: SimonC.eu

    Bitte nicht wundern, wenn meine Aktivitäten im Forum etwas langsamer sind, ich baue gerade mein Nebengewerbe zum Vollgewerbe aus.
    Ich versuche auf euch zurückzukommen :)
    @Pixxxas Arbeitest du im Code mit Bildern oder großen Byte-Arrays? Die Bilder musst du disposen, sobald du sie nicht mehr brauchst. Schreib dir eine Methode, die die Bilder verwirft, die du nicht mehr brauchst, und die lädt, die du jetzt brauchst.
    Solltest du eine Klasseninstanz nicht mehr brauchen – und angenommen darin sind große Objekte ( 2GB Videodatei als Byte-Array) – dann entferne die Instanz mit
    MeineKlasse = Nothing, bevor du eine neue Instanz erstellst. Ich weiß ja nicht, was dein Ziel ist.
    Wie siycah bereits erwähnte: es gibt zwar eine automatische Garbage Collection. Aber die greift nicht ständig und sofort ein.