2009-07-06 10 views
38

Según tengo entendido, hay un límite de 2 GB para las instancias individuales en .NET. No le he prestado mucha atención, ya que he trabajado principalmente en sistemas operativos de 32 bits hasta ahora. En 32 pero es más o menos una limitación artificial de todos modos. Sin embargo, me sorprendió bastante saber que this limitation also applies on 64 bit .NET. Como colecciones como List<T> usan una matriz para almacenar elementos, eso significa que una aplicación .NET que se ejecuta en 32 bits podrá contener el doble de elementos de tipo de referencia en una lista en comparación con la misma aplicación que se ejecuta en 64 bits . Eso es bastante sorprendente, imo.¿Objetos únicos aún están limitados a 2 GB de tamaño en CLR 4.0?

¿Alguien sabe si esta limitación se aborda en CLR 4.0 (no tengo una instalación 4.0 disponible en este momento).

+6

Actualización 2012: A partir de .NET 4.5, en sistemas x64, los desarrolladores pueden asignar objetos de mayor tamaño (mucho más grande) de 2 GB. El límite de 2 GB está muerto. http://www.centerspace.net/blog/nmath/large-matrices-and-vectors/?preview=true&preview_id=221&preview_nonce=7d1678c20c – Paul

+2

El enlace correcto parece ser http://www.centerspace.net/blog/nmath/ large-matrices-and-vectors/ –

+1

Incluso los enlaces corregidos están muertos :( – RBT

Respuesta

50

Es peor que eso, tu espacio de proceso, cuando trabajas en .NET en 32 bits es mucho menor que el límite teórico. En las aplicaciones .NET de 32 bits, mi experiencia es que siempre tenderá a tener errores de memoria en algún lugar alrededor de 1.2-1.4gb de memoria (algunas personas dicen que pueden llegar a 1.6 ... pero nunca lo he visto) Por supuesto, esto no es un problema en los sistemas de 64 bits.

Dicho esto, una única matriz de 2 GB de tipos de referencia, incluso en sistemas de 64 bits, es una gran cantidad de objetos. Incluso con referencias de 8 bytes, tiene la capacidad de asignar una matriz de 268,435,456 referencias de objetos, cada una de las cuales puede ser muy grande (hasta 2 GB, más si utilizan objetos anidados). Eso es más memoria de la que la mayoría de las aplicaciones necesitarían realmente.

Uno de los miembros de CLR team blogged about this, con algunas opciones para evitar estas limitaciones. En un sistema de 64 bits, hacer algo como su BigArray <T> sería una solución viable para asignar cualquier cantidad de objetos en una matriz, mucho más que el límite de 2gb para un solo objeto. P/Invoke puede permitirle asignar matrices más grandes también.


Editar: debería haber mencionado esto, también - no creo que este comportamiento ha cambiado en absoluto para .NET 4. El comportamiento ha sido sin cambios desde el inicio de .NET.


Editar: .NET 4.5 ahora tendrán la opción de x64 para permitir explícitamente los objetos sean más de 2 GB mediante el establecimiento de gcAllowVeryLargeObjects en el app.config.

+0

Soy consciente de todas las limitaciones en 32 bits, pero ese no es realmente el punto de mi pregunta. La sorpresa fue que las cosas son realmente peores en 64 bits. Echaré un vistazo a la publicación del blog. Gracias por el enlace. –

+0

No hay problema - Acabo de agregar eso porque realmente no es peor en 64 bits que en 32 bits. El límite teórico es 1/2 de los objetos, pero como está realmente limitado a un total de 1,4 gb de espacio de proceso, no hay forma de hacer una matriz de referencias de objetos, incluso cerca de la mitad del tamaño permitido. (Cada referencia requiere que apunte a algo, así como también al tamaño de la referencia ... por lo que realmente la mayoría de las veces alcanza un valor de 1/4gb en referencias en .NET de 32 bits). –

+0

En respuesta a Editar: sospecho que tienes razón. Hasta donde puedo decir, la limitación siempre ha estado presente y no he podido encontrar nada que indique que se haya cambiado el límite. Puedo entender por qué MS puede no querer abordar, pero es realmente extraño que cambiar a 64 bits realmente rinda menos "espacio" para colecciones individuales de todos modos. –

13

Esto es un gran problema en el campo numérico. Cualquiera que use bibliotecas de clases numéricas en .NET tiene sus matrices almacenadas como matrices debajo. Esto es para que se puedan llamar las bibliotecas nativas para hacer el cálculo numérico. El límite de 2 GB dificulta seriamente el tamaño de las matrices posibles en .NET de 64 bits. Más here.

+1

Hemos hablado con Microsoft sobre este problema. Es poco probable que se solucione en .NET 4.0, pero parecían muy receptivos para encontrar una solución. Creo que terminaremos con arreglos indexados largos, pero más probablemente algún tipo de objeto blob gigante. –

+0

¿Cómo se compara el rendimiento de una matriz 65536 * 65536 de float con 65536 arrays de 65536 flotantes? El rendimiento de 256 matrices de 256 flotantes será inferior al de una matriz 256 * 256, ya que esta última tendrá una mejor localidad de memoria caché y la primera no, pero si se accede a las filas de una matriz que están suficientemente localizadas para beneficiarse de la localidad de caché, creo que uno de los procesadores sería capaz de almacenar en caché las referencias de la tabla de objetos. – supercat

15

.NET Framework 4.5 permite la creación de matrices de más de 2 GB en plataformas de 64 bits. Esta característica no está activada por defecto, tiene que estar habilitada a través del archivo config usando el elemento gcAllowVeryLargeObjects.

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

+0

No me había dado cuenta. Gracias por el enlace. –

+0

¿Todavía solo 4 GB? ¿Por qué no pueden hacer real de 64 bits? –

+0

@Rick ¿dónde ves 4GB? –

Cuestiones relacionadas