2009-07-06 20 views
38

Wie ich es verstehe, gibt es eine Grenze von 2 GB für einzelne Instanzen in .NET. Ich habe dem nicht viel Aufmerksamkeit geschenkt, da ich bisher hauptsächlich an 32-Bit-Betriebssystem gearbeitet habe. Am 32 ist es aber mehr oder weniger eine künstliche Begrenzung. Ich war jedoch ziemlich überrascht, dass das this limitation also applies on 64 bit .NET zu erfahren.Einzelobjekte sind in CLR 4.0 noch auf 2 GB begrenzt?

Da Sammlungen wie List<T> ein Array zum Speichern von Elementen verwenden, bedeutet dies, dass eine .NET-Anwendung mit 32 Bit doppelt so viele Referenztypenelemente in einer Liste enthalten kann wie die gleiche Anwendung mit 64 Bit . Das ist ziemlich überraschend.

Weiß jemand, ob diese Einschränkung in CLR 4.0 angesprochen wird (ich habe momentan keine 4.0-Installation zur Hand).

+6

-Update 2012: Ab .NET 4.5, auf x64-Systemen können Entwickler jetzt zuweisen Objekte größer (viel größer) als 2GB. Das Limit von 2 GB ist tot. http://www.centerepace.net/blog/nmath/large-matrices-and-vectors/?preview=true&preview_id=221&preview_nonce=7d1678c20c – Paul

+2

Korrekter Link scheint http://www.centerepace.net/blog/nmath/ zu sein large-matrices-and-vectors/ –

+1

Auch die korrigierten Links sind tot :( – RBT

Antwort

50

Es ist schlimmer als das - Sie sind Prozessraum, wenn Sie in .NET in 32bit arbeiten ist viel kleiner als das theoretische Limit. In 32-Bit-.NET-Anwendungen habe ich die Erfahrung, dass Sie immer mit Fehlern bei der Speicherbelegung von 1,2 bis 1,4 GB beginnen (manche sagen, sie können 1,6 erreichen) ... aber das habe ich noch nie gesehen). Natürlich ist dies bei 64-Bit-Systemen kein Problem.

Das heißt, eine einzige 2 GB-Array von Referenztypen, sogar auf 64-Bit-Systemen, ist eine riesige Menge von Objekten. Selbst mit 8-Byte-Referenzen haben Sie die Möglichkeit, ein Array von 268.435.456 Objektreferenzen zuzuordnen, von denen jeder sehr groß sein kann (bis zu 2 GB, mehr, wenn verschachtelte Objekte verwendet werden). Das ist mehr Speicher, als die meisten Anwendungen wirklich benötigen würden.

Eines der Mitglieder der CLR team blogged about this, mit einigen Optionen für die Möglichkeiten, um diese Einschränkungen zu umgehen. Auf einem 64-Bit-System wäre das Ausführen von etwas wie seinem BigArray <T> eine praktikable Lösung, um eine beliebige Anzahl von Objekten in ein Array zuzuteilen - viel mehr als das Limit von 2 GB für einzelne Objekte. Mit P/Invoke können Sie auch größere Arrays zuweisen.


Edit: Ich sollte dies erwähnt haben, als auch - ich glaube nicht, dieses Verhalten überhaupt für .NET 4. Das Verhalten seit Anfang .NET wurde unverändert geändert hat.


Edit: .NET 4.5 wird nun die Möglichkeit, in x64 müssen explizit Objekte erlauben 2gb größer zu sein als durch gcAllowVeryLargeObjects in der app.config Einstellung.

+0

Ich kenne alle Einschränkungen auf 32 Bit, aber das ist nicht wirklich der Punkt meiner Frage. Die Überraschung war, dass die Dinge auf 64 Bit tatsächlich schlechter sind. Ich werde mir den Blogbeitrag ansehen. Danke für den Link. –

+0

Kein Problem - ich habe das nur hinzugefügt, weil es in 64bit wirklich nicht schlechter ist als 32bit. Die theoretische Grenze ist die Hälfte der Objekte, aber da Sie wirklich auf insgesamt 1,4 GB Prozessraum beschränkt sind, gibt es keine Möglichkeit, ein Array von Objektreferenzen annähernd auf die Hälfte der zulässigen Größe zu bringen. (Jede Referenz erfordert, dass sie auf etwas zeigt, ebenso wie auf die Größe der Referenz .... so dass Sie wirklich die meiste Zeit rund 1/4gb Referenzen in .NET 32bit ausschließen). –

+0

Als Antwort auf Edit: Ich vermute, du hast Recht. Soweit ich das beurteilen kann, war die Beschränkung immer da und ich konnte nichts finden, was darauf hinwies, dass das Limit geändert wurde. Ich kann verstehen, warum MS nicht ansprechen möchte, aber es ist wirklich komisch, dass der Wechsel zu 64 Bit sowieso weniger Platz für einzelne Sammlungen bringt. –

13

Dies ist eine große Sache im numerischen Bereich. Jeder, der numerische Klassenbibliotheken in .NET verwendet, hat seine Matrizen als Arrays darunter gespeichert. Dies ist so, native Bibliotheken können aufgerufen werden, um die Zahlen zu knacken. Das 2-GB-Limit beeinträchtigt die Größe von Matrizen, die in 64-Bit-.NET möglich sind. Mehr here.

+1

Wir haben mit Microsoft über dieses Problem gesprochen. Es ist unwahrscheinlich, dass sie in .NET 4.0 behoben werden, aber sie schienen sehr aufgeschlossen zu sein, um eine Lösung zu finden. Ich denke, wir werden mit langen indizierten Arrays enden, aber eher mit einer Art riesigem Blob-Objekt. –

+0

Wie vergleicht sich die Leistung eines 65536 * 65536 Floats mit dem von 65536 Arrays von 65536 Floats? Die Leistung von 256 Arrays von 256 Floats wird schlechter sein als die eines 256 * 256-Arrays, da letzteres eine bessere Cache-Lokalität haben wird und das erstere nicht, aber wenn man auf Zeilen einer Matrix zugreift, die ausreichend lokalisiert sind, um davon zu profitieren Von Cache-Lokalität würde ich denken, dass der Prozessor in der Lage wäre, die Objekttabellenreferenzen zwischenzuspeichern. – supercat

15

.NET Framework 4.5 ermöglicht das Erstellen von Arrays größer als 2 GB auf 64-Bit-Plattformen. Diese Funktion ist standardmäßig nicht aktiviert, sie muss über die Konfigurationsdatei mit dem Element gcAllowVeryLargeObjects aktiviert werden.

http://msdn.microsoft.com/en-us/library/hh285054(v=vs.110).aspx

+0

hatte ich nicht bemerkt. Danke für den Link. –

+0

Immer noch nur 4 GB !? Warum können sie nicht wirklich 64-Bit machen? –

+0

@Rick wo siehst du 4GB? –

Verwandte Themen