Ergebnis 1 bis 11 von 11
  1. #1
    ... Avatar von flasher4401
    Registriert seit
    May 2008
    Beiträge
    668

    Standard Out Of Memory Exeception --> Großes Byte Array

    Hallo!



    Ich bekomme eine Out Of Memory Exception, wenn ich versuche ein Byte[] aus den Resourcen abzurufen.
    Mein Ziel ist es das Byte-Array in eine Datei zu schreiben (.rar).

    Das war mein erster Ansatz:
    Code:
    fs.Write(t.Properties.Resources.t, 0, t.Properties.Resources.t.Length);
    fs.Close()
    Doch dies brachte mir eine Out Of Memory Exception. Daraufhin habe ich mal rumgegoogelt und herrausgefunden, dass es schlauer ist größere Mengen an Daten in kleinen Mengen zu schreiben (chunks):
    Code:
    int incomingoffset = 0;
    
                    while (incomingoffset < t.Properties.Resources.t.Length)
                    {
                        int length = Math.Min(65536, t.Properties.Resources.t.Length - incomingoffset);
    
                        fs.Write(t.Properties.Resources.t, incomingoffset, length);
                        incomingoffset += length;
                    }
    
                    fs.Close();
    Das Ergebnis von diesem hoffnungsvollen Versuch sieht man oben im Bild.

    Ist die Datenmenge (ca.600mb) vll. einfach zu viel ??

    Ich hatte mir auch schon überlegt, dass das Problem vll. direkt beim einlesen der Ressource liegt: (Automatischer Generierter Code von VS2010)
    Code:
    internal static byte[] t {
                get {
                    object obj = ResourceManager.GetObject("t", resourceCulture);
                    return ((byte[])(obj));
                }
            }
    Hier wird das Objekt ja wieder an einem Stück in ein Byte[] eingelesen(konvertiert), liegt hier vll. das Problem?

    -flasher

  2. #2
    Mitglied
    Registriert seit
    Oct 2004
    Beiträge
    560

    Standard Re: Out Of Memory Exeception --> Großes Byte Array

    Jop, du hast sofort das byte-Array und dieses belegt dir eben die 600mb an Speicher.
    Ich würde mir die Ressource als Stream geben lassen und diese gepuffert wegschreiben.
    siehe hier

  3. #3
    Mitglied
    Registriert seit
    Jan 2012
    Beiträge
    10

    Standard Re: Out Of Memory Exeception --> Großes Byte Array

    hi,

    bist du sicher dass jedes Feld [x] im Byte Array auch nur mit 1 byte Daten befüllt wird?

  4. #4
    \o/ Avatar von sumisumi
    Registriert seit
    Jan 2008
    Beiträge
    4.039

    Standard Re: Out Of Memory Exeception --> Großes Byte Array

    Dafür sorgt doch schon das Typsystem, es geht gar nicht anders.

  5. #5
    ...

    (Threadstarter)

    Avatar von flasher4401
    Registriert seit
    May 2008
    Beiträge
    668

    Standard Re: Out Of Memory Exeception --> Großes Byte Array

    Zitat Zitat von tras Beitrag anzeigen
    Jop, du hast sofort das byte-Array und dieses belegt dir eben die 600mb an Speicher.
    Ich würde mir die Ressource als Stream geben lassen und diese gepuffert wegschreiben.
    siehe hier
    Ok Danke, werde ich ausprobiern

    Aber trotzdem versteh ich nicht warum ich diesen Fehler erhalte, denn normalerweise sollte es ja kein Problem sein 600mb in den Arbeitsspeicher zu laden, wofür gibt es sonst 4GB+ Ram Sticks ??

    -flasher

  6. #6
    Mr. Floppy is da

    Moderator

    Avatar von Larius
    Registriert seit
    Aug 2004
    Ort
    Österreich
    Beiträge
    4.913

    Standard Re: Out Of Memory Exeception --> Großes Byte Array

    Weil der Arbeitsspeicher in mehrere Teile unterteilt ist. Schau dir mal die Begriffe Stack & Heap an sowie Speicherfragmentierung. Wenn du Pech hast sind genau 599 MB noch frei und das letzte MB würd schon im anderen Bereich liegen, wo man nicht drauf zugreifen kann.

  7. #7
    \o/ Avatar von sumisumi
    Registriert seit
    Jan 2008
    Beiträge
    4.039

    Standard Re: Out Of Memory Exeception --> Großes Byte Array

    Der .net GC ist ein "compacting GC", von daher sollte keine großartige Fragmentierung bzw keine Lücken auftreten!?

  8. #8
    Mitglied
    Registriert seit
    Mar 2007
    Beiträge
    2.700

    Standard Re: Out Of Memory Exeception --> Großes Byte Array

    Dann hast du die Aufgabe des GC falsch verstanden. Der sorgt lediglich dafür dass innerhalb des von der Anwendung belegten Speichers keine Fragmentierung auftritt. Das Problem ist allerdings die Fragementierung des Hauptspeichers an sich. Wenn du versuchst ein 600 Mbyte großes Byte-FELD zu initialisieren (allokieren ist noch kein Problem), so muss das OS einen zusammenhängenden, 600 Mbyte großen Block mit fortlaufenden Speicheradressen im Speicher finden. Durch die Fragmentierung innerhalb des RAMs hat man allerdings selten solche großen Blöcke in einem Stück frei weshalb es dann zu der Exception kommt.

    Die Lösung ist simpel: Anstelle der 1D-Arrays auf einen 2D-Array wechseln. Der äußere Array enthält dann nur noch Referenzen auf jeweils 1MB große Bytefelder. Damit muss das OS anstelle von 1x 600MB nur noch 600x jeweils einen kleinen 1MB großen Block reservieren - was bei ausreichend RAM absolut unproblematisch ist. Das war auch mit den Chunks gemeint, die Datenstruktur an sich auf zu brechen.

    Zudem ist der von VS2010 an dieser Stelle automatisch generierte Getter extrem blöd, bei einer 600MB großen Ressource diese als Kopie und nicht als Referenz zu übergeben ist Wahnsinn und performancetechnisch ein Alptraum. Entweder du schreibst den Getter so um, dass er dir eine Referenz anstelle einer Kopie gibt, oder du baust dir einen zweiten Getter der direkt nur einzelne Chunks zurück gibt und nicht das komplette Feld.

  9. #9
    Mr. Floppy is da

    Moderator

    Avatar von Larius
    Registriert seit
    Aug 2004
    Ort
    Österreich
    Beiträge
    4.913

    Standard Re: Out Of Memory Exeception --> Großes Byte Array

    Ist der Echtzeit oder genauso "random" wie der von Java? Also wenn das Objekt zum Löschen ist wirds auch gelöscht und nicht nur markiert, damits irgendwann der GC löscht?

    Compacting GC - schiebt der den Speicher, welcher belegt ist, zusammen? Ansonsten hat man ja noch immer das Problem der Speicherfragmentierung.

  10. #10
    hat Spaß dran... Avatar von 12345z
    Registriert seit
    Aug 2007
    Beiträge
    1.804

    Standard Re: Out Of Memory Exeception --> Großes Byte Array

    Ist der Echtzeit oder genauso "random" wie der von Java? Also wenn das Objekt zum Löschen ist wirds auch gelöscht und nicht nur markiert, damits irgendwann der GC löscht?
    Der GC "markiert" genauso und gelöscht wird zu einem günstigen Zeitpunkt. In den alten .Net Versionen war das jedenfalls so - kann sich auch was geändert haben.

    Allerdings kann (konnte?) man den GC auch manuell zu einem determinierten Zeitpunkt "collecten" lassen.

  11. #11
    Mitglied
    Registriert seit
    Mar 2007
    Beiträge
    2.700

    Standard Re: Out Of Memory Exeception --> Großes Byte Array

    Genauso "random" wie der von Java, sprich hat auch nen eigenen kleinen Memory-Pool um exzessize maloc-Aufruf zu vermeiden wenn man andauernd in der Schleife Speicher neu allokiert.

    Compacting GC schiebt den Speicher innerhalb der Anwendung zusammen um die interne Fragmentierung und die damit auftretenden Memoryleaks zu eliminieren, deswegen sind in .net auch keine Pointer erlaubt bzw. man muss den GC für die jeweiligen Sektionen / Variablen explizit deaktivieren um Pointer nutzen zu dürfen (C# / VB.net). Die externe Fragementierung auf OS-Ebene bleibt aber bestehen und ist hier auch das eigentliche Problem.

  12.  
     
     

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •