Autor |
Beitrag |
m4ko
Hält's aus hier
Beiträge: 3
|
Verfasst: Mi 16.06.10 12:02
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
      
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Mi 16.06.10 14:45
Hallo und  ,
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 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
      
Beiträge: 503
Erhaltene Danke: 34
W7 (x64) Ultimate
C# / VB.NET (VS2010 Ultimate)
|
Verfasst: Mi 16.06.10 14:49
Oder als 64Bit-Programm kompilieren
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.
Zuletzt bearbeitet von bakachan am Mi 16.06.10 14:51, insgesamt 1-mal bearbeitet
|
|
danielf
      
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Mi 16.06.10 14:50
Ach... da hätte ich mal mein Zitat genauer lesen sollen, bzw den Wiki-Artikel bis zum Ende
Aber schön, dass es sich so schnell klärt 
|
|
m4ko 
Hält's aus hier
Beiträge: 3
|
Verfasst: 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
      
Beiträge: 157
Erhaltene Danke: 19
Win XP
C#, Fortran 95 - Visual Studio
|
Verfasst: 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ü
_________________ Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Mi 16.06.10 19:23
|
|
gfoidl
      
Beiträge: 157
Erhaltene Danke: 19
Win XP
C#, Fortran 95 - Visual Studio
|
Verfasst: Mi 16.06.10 22:17
Hallo Kha,
danke für die Berichtung auf 2GB - stimmt natürlich.
mfG Gü
_________________ Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!
|
|
m4ko 
Hält's aus hier
Beiträge: 3
|
Verfasst: Do 17.06.10 15:05
|
|