-
27. 01. 2012, 14:53 #1
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:
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:fs.Write(t.Properties.Resources.t, 0, t.Properties.Resources.t.Length); fs.Close()
Das Ergebnis von diesem hoffnungsvollen Versuch sieht man oben im Bild.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();
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)
Hier wird das Objekt ja wieder an einem Stück in ein Byte[] eingelesen(konvertiert), liegt hier vll. das Problem?Code:internal static byte[] t { get { object obj = ResourceManager.GetObject("t", resourceCulture); return ((byte[])(obj)); } }
-flasher
-
27. 01. 2012, 15:22 #2Mitglied
- Registriert seit
- Oct 2004
- Beiträge
- 560
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
-
27. 01. 2012, 17:57 #3Mitglied
- Registriert seit
- Jan 2012
- Beiträge
- 10
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?
-
27. 01. 2012, 18:10 #4
Re: Out Of Memory Exeception --> Großes Byte Array
Dafür sorgt doch schon das Typsystem, es geht gar nicht anders.
-
27. 01. 2012, 21:10 #5
-
27. 01. 2012, 23:32 #6
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.
-
28. 01. 2012, 03:37 #7
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!?
-
28. 01. 2012, 12:31 #8Mitglied
- Registriert seit
- Mar 2007
- Beiträge
- 2.700
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.
-
28. 01. 2012, 12:32 #9
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.
-
28. 01. 2012, 12:56 #10
Re: Out Of Memory Exeception --> Großes Byte Array
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.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?
Allerdings kann (konnte?) man den GC auch manuell zu einem determinierten Zeitpunkt "collecten" lassen.
-
28. 01. 2012, 22:23 #11Mitglied
- Registriert seit
- Mar 2007
- Beiträge
- 2.700
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.
-


Zitieren


mehr lesen...







Occupy Kiel: Massiver Sachschaden...
Heute, 20:15 in gulli:news