Nicht genügend Arbeitsspeicher

  • VB.NET
  • .NET (FX) 4.5–4.8

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

    Nicht genügend Arbeitsspeicher

    Hallo Profis

    Ich hab da eine simple Fehlermeldung ("Nicht genügend Arbeitsspeicher"), die ich mir aber ganz und gar nicht erklären kann. Hintergrund: Ich will 400 Urlaubsfotos in einem Ordner umbenennen nach Aufnahmedatum und -zeit. Das funktioniert mit der Lösung von vb-magazin.de/forums/forums/t/4586.aspx auch fast:

    VB.NET-Quellcode

    1. Dim Ordner As New DirectoryInfo(Ordnerpfad)
    2. Dim DateiListe As FileInfo() = Ordner.GetFiles("*.jpg")
    3. For Each Datei As FileInfo In DateiListe
    4. Dim Image As Image = Image.FromFile(Datei.FullName) '<---- Zuwenig Arbeitsspeicher
    5. Dim enc As Encoding = Encoding.Default
    6. For Each Info As PropertyItem In Image.PropertyItems
    7. Select Case Info.Id
    8. '...
    9. End Select
    10. Next
    11. Next


    Allerdings bleibt das Programm aber nach etwa 60 Fotos (je ca. 10MB) stecken mit der erwähnten Fehlermeldung (aufgeworfen in der fünften, oben markierten Zeile). Mach ich aber aus dem Ordner mit den 400 Fotos acht Ordner mit je 50 Fotos und starte mein Programm achtmal, gibt's KEINE Probleme (der Grund kann also nicht eine korrupte Fotodatei sein, wie hier im Forum auch schon mal diskutiert). Das kann ich mir nun überhaupt nicht erklären. Der Speicher "Image" wird doch bei jedem "Each" wieder neu überschrieben und muss nicht zurückgegeben werden??? Ein "Image = Nothing" am Schluss von "Each" löste denn auch nicht das Problem. Der Fehler tritt in der IDE im Schrittmodus wie auch als .exe auf. Hat da der Interpreter/Compiler ein Speicherproblem, das Programm ist doch so weit i.O., oder? Wer kann mir einen Tipp geben? Habe übrigens Win7 (64Bit) und VisualStudio Pro 2012, Version 11.0.61030.00 Update 4.

    Danke schon mal im Voraus

    Bernhard
    @Grüter Wenn Du fertig bist mit dem Umbenennen musst Du das Image disposen.
    Poste mal die komplette Prozedur.
    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!
    Danke, Rod und ChOoSeMyNaMe, das war die Lösung. Verstehen tu' ich zwar diese Lösung immer noch nicht, deshalb ein prinzipielles Nachhaken: Wenn ich im n-ten Schleifendurchgang einen Speicherplatz reserviere, dann ist doch dieser Speicher im n+1-ten Durchgang obsolet (er gilt doch nur für die Dauer des n-ten Durchganges, sonst müsste ich ihn ja VOR der Schleife deklarieren) und kann auf jeden Fall vernichtet werden. Warum muss ich denn dies tun und warum nimmt mir der Garbage Collector diesen Job nicht ab?

    Danke für die Aufklärung,

    Bernhard
    @Grüter Das Problem besteht darin, dass ein Image unmanaged Ressourcen benötigt.
    Wenn Dein Bild nicht disposed wird, landen die nicht freigegebenen Speicherblöcke auf dem "Nirwana-Müll" und werden erst im Finalizer beräumt, das dürfte bei Dir das Ende des Programms sein.
    Also immer schön aufräumen.
    Bilder
    • Analyse.jpg

      22,77 kB, 430×260, 148 mal angesehen
    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!

    Grüter schrieb:

    Wenn ich im n-ten Schleifendurchgang einen Speicherplatz reserviere, dann ist doch dieser Speicher im n+1-ten Durchgang obsolet
    Jo, das ist grundsätzlich richtig, und gehört zur Grund-Architektur von .Net (Stichwort GarbageCollection).
    Aber - haben die anderen schon gesagt - es gibt da "Ausnahmen", die aus technischen Gründen in einer Weise gestrickt sind, dass der GC sie nicht korrekt entladen kann.

    Für derlei Ausnahmen (es sind leider ziemlich viele) ist der sog. "Dispose-Pattern" (kannste googeln) geschaffen.
    Problematische Klassen implementieren das IDisposable-Interface, und stellen so einheitlich eine Methode bereit, wie sie sich selber aufräumen.
    Und das geht dann nicht mehr automatisch, sondern man muss die Dispose()-Methode dann halt aufrufen.
    Hat sich zwar schon erledigt, aber vielleicht ist es trotzdem nützlich:
    Was sind verwaltete / nicht verwaltete Ressourcen
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils