Entwickler-Ecke
Basistechnologien - C# Maximaler Speicher
m4ko - Mi 16.06.10 12:02
Titel: C# Maximaler Speicher
Hallo C#Sharp Community!
Ich habe mich grade erst registriert und deshalb ein kurzes: Hallo!
Der Grund meiner Anmeldung ist folgender:
Ich möchte sehr große Bilddaten verarbeiten.
Umgebung:
Ich habe hier PCs zur Verfügung die mit 12 bis 24 GB RAM und Windows 7 64bit ausgestattet sind. Nun habe ich mir verschiedene C# Programme gebastelt um auszuloten wie viel Speicher ich in Form von Arrays allozieren kann. Leider kann ich den verfügbaren Arbeitsspeicher nicht mal ansatzweise ausnutzen. Hier ein Beispiel dazu:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
| PerformanceCounter PC = new PerformanceCounter("Memory", "Available Bytes"); Console.WriteLine("Available Memory: " + ToFuzzyByteString(PC.NextValue())); Console.WriteLine("");
int[] ManyInts; for (int i = 20; i < 30; i++) { try { AmountInBytes = Math.Pow(2, i) * 4; Console.Write("Allocating 2^" + i + " ints (= " + ToFuzzyByteString(AmountInBytes) + ")..."); ManyInts = null; System.Threading.Thread.Sleep(100); ManyInts = new int[Convert.ToInt32(Math.Pow(2, i))]; for (int j = 0; j < ManyInts.Length; j++) { ManyInts[j] = 5; } Console.WriteLine(" OK"); } catch (Exception exc) { Console.WriteLine(" Failed"); Console.WriteLine("Exception: " + exc.Message); break; } } |
Ausgabe dazu:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| Available Memory: 6,61 GB
Allocating 2^20 ints (= 4 MB)... OK Allocating 2^21 ints (= 8 MB)... OK Allocating 2^22 ints (= 16 MB)... OK Allocating 2^23 ints (= 32 MB)... OK Allocating 2^24 ints (= 64 MB)... OK Allocating 2^25 ints (= 128 MB)... OK Allocating 2^26 ints (= 256 MB)... OK Allocating 2^27 ints (= 512 MB)... OK Allocating 2^28 ints (= 1 GB)... OK Allocating 2^29 ints (= 2 GB)... Failed Exception: Exception of type 'System.OutOfMemoryException' was thrown. |
Dies ist auf einem 8GB Win7 Rechner erstellt worden. Nun habe ich gedacht "OK. 2GB am Stück gehen nicht... dann machen wir halt kleine Chunks."
C# Code:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| double AmountInBytes = Math.Pow(2, 24) * 4; Console.Write("Allocating lots of 2^24 ints (= " + ToFuzzyByteString(AmountInBytes) + ")..."); List<int[]> arrayList = new List<int[]>(); for (int i = 0; i < 10000; i++) { try { Console.Write(i + "..."); arrayList.Add(new int[Convert.ToInt32(Math.Pow(2, i))]); for (int j = 0; j < arrayList[i].Length; j++) { arrayList[i][j] = 5; } Console.WriteLine(" OK (=" + ToFuzzyByteString(AmountInBytes * i) + ")"); } catch (Exception exc) { Console.WriteLine(" FAILED"); break; } } |
Ausgabe:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
| Allocating lots of 2^24 ints (= 64 MB)...0... OK (=0 bytes) 1... OK (=64 MB) 2... OK (=128 MB) 3... OK (=192 MB) 4... OK (=256 MB) 5... OK (=320 MB) 6... OK (=384 MB) 7... OK (=448 MB) 8... OK (=512 MB) 9... OK (=576 MB) 10... OK (=640 MB) 11... OK (=704 MB) 12... OK (=768 MB) 13... OK (=832 MB) 14... OK (=896 MB) 15... OK (=960 MB) 16... OK (=1 GB) 17... OK (=1,06 GB) 18... OK (=1,12 GB) 19... OK (=1,18 GB) 20... OK (=1,25 GB) 21... OK (=1,31 GB) 22... OK (=1,37 GB) 23... OK (=1,43 GB) 24... OK (=1,5 GB) 25... OK (=1,56 GB) 26... OK (=1,62 GB) 27... OK (=1,68 GB) 28... OK (=1,75 GB) 29... FAILED |
Also habe ich nun ein Array mit 28 * 2 hoch 24 ints (~1,75GB). Das ist natürlich zu wenig bei 8GB RAM und 6,4GB freiem RAM.
Hat jemand eine Idee wodran das liegt? Oder einen Tip wie ich mehr Speicher bekomme? Oder gibt es vielleicht Abhilfe mit Visual Studio 2010?
danielf - Mi 16.06.10 14:45
Hallo und :welcome:,
ich hab zwar kein konrekte Lösung, aber ich erinnere mich daran, dass es noch eine Einschränkung pro Prozess gibt. Deshalb hab ich mal danach gegoogelt und bin auf
Wikipedia [
http://de.wikipedia.org/wiki/4-GB-Grenze] auf folgende Aussage gestoßen:
Zitat: |
Unter Windows kann ein einzelner 32bit-Prozess generell nicht mehr als 2 GB belegen, außer IMAGE_FILE_LARGE_ADDRESS_AWARE ist im Header der Anwendung aktiviert (dann sind bis zu 4 GB möglich) |
.
Also musst du wohl mal schauen, wie du das umgehen kannst.
Was willst du den genau machen?
Vielleicht kannst du es auf mehrere Prozesse auslagern ...
Gruß
bakachan - Mi 16.06.10 14:49
Oder als 64Bit-Programm kompilieren :wink:
Ich gehe mal davon aus das die PCs bei den Speichergrößen (8/12/24 GB) sowieso mit 64Bit-Systemen laufen um den Speicher überhaupt nutzen zu können.
danielf - Mi 16.06.10 14:50
Ach... da hätte ich mal mein Zitat genauer lesen sollen, bzw den Wiki-Artikel bis zum Ende :D
Aber schön, dass es sich so schnell klärt :)
m4ko - Mi 16.06.10 15:29
Der Prozess ist natürlich 64bit ;).
Ich habe es auch mittlerweile hinbekommen mehr Speicher zu allozieren.
Hintergrund:
Auch wenn das Programm 64bit kompiliert ist und die Pointer im die im Hintergrund werkeln 64bit Pointer so sind die Array-Index-Dinger immer noch nur 32bit fähig. Das bedeutet: Man kann kein Array > 32bit anlegen. Man kann aber mehrere Arrays anlegen! Allerdings dürfen die nicht in einer Liste stehen.
Beispiel: GEHT NICHT ÜBER ~1,7GB!
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| List<int[]> arrayList = new List<int[]>(); for (int i = 0; i < 10000; i++) { arrayList.Add(new int[Convert.ToInt32(Math.Pow(2, 24))]); for (int j = 0; j < arrayList[i].Length; j++) { arrayList[i][j] = 5; } } |
Beispiel: GEHT UNENDLICH (bisher) :)
C#-Quelltext
1: 2: 3: 4: 5:
| int arrayLength = (int)(1024*1024*1024/4); int[] arrONE = new int[arrayLength]; int[] arrTWO = new int[arrayLength]; int[] arrTHREE = new int[arrayLength]; ... |
Da ich aber ein mega riesen Array haben möchte werde ich mir wohl einen Index dafür basteln müssen der einen int64 Offset auf mehrere int32 Arrays verteilt. Hm. jemand dazu schicke Ideen?
gfoidl - Mi 16.06.10 15:35
Hallo,
weiters wurde die CLR auch so designed dass die maximale Objektgröße 1GB ist. Ob das in .net 4.0 geändert wurde weiß ich nicht. D.h. aber nicht dass mehrer 1GB-Objekte existieren dürfen ;-)
mfG Gü
Kha - Mi 16.06.10 19:23
Ebenfalls :welcome: !
m4ko hat folgendes geschrieben : |
Auch wenn das Programm 64bit kompiliert ist und die Pointer im die im Hintergrund werkeln 64bit Pointer so sind die Array-Index-Dinger immer noch nur 32bit fähig. |
Stimmt. Nur, wo soll das in deinem Programm mit den maximalen Indizes 10000 und 5 eine Rolle spielen ;) ?
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| Console.Write("Allocating lots of 2^24 ints (= 64 MB)..."); List<int[]> arrayList = new List<int[]>(); for (int i = 0; i < 10000; i++) { try { Console.Write(i + "..."); arrayList.Add(new int[1 << 24]); Console.WriteLine(" OK (= " + 64 * i + " MB)"); } catch (OutOfMemoryException) { Console.WriteLine(" FAILED"); break; } } |
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| ... 171... OK (= 10944 MB) 172... OK (= 11008 MB) 173... OK (= 11072 MB) 174... OK (= 11136 MB) 175... OK (= 11200 MB) 176... OK (= 11264 MB) 177... OK (= 11328 MB) 178... OK (= 11392 MB) 179... OK (= 11456 MB) 180... OK (= 11520 MB) 181... OK (= 11584 MB) 182... OK (= 11648 MB) 183... FAILED |
Ganz sicher, dass du für x64 oder AnyCPU kompiliert hast :nixweiss: ?
gfoidl hat folgendes geschrieben : |
weiters wurde die CLR auch so designed dass die maximale Objektgröße 1GB ist. |
Soweit ich weiß, sind es
2 [
http://blogs.msdn.com/b/joshwil/archive/2005/08/10/450202.aspx].
gfoidl hat folgendes geschrieben : |
D.h. aber nicht dass mehrer 1GB-Objekte existieren dürfen ;-) |
Ich nehme mal an, das darf man zu einer doppelten Verneinung ergänzen :D ?
gfoidl - Mi 16.06.10 22:17
Hallo Kha,
danke für die Berichtung auf 2GB - stimmt natürlich.
mfG Gü
m4ko - Do 17.06.10 15:05
Kha hat folgendes geschrieben : |
Nur, wo soll das in deinem Programm mit den maximalen Indizes 10000 und 5 eine Rolle spielen ;) ? |
Hmmmmmm. Da muss ich wohl tatsächlich 32bit kompiliert haben. Ich kann den Fehler @ 1,7GB nicht mehr reproduzieren. Danke für den Hinweis!
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!