significa que mejor mayor mas internet gigabyte cuanto cual .net arrays limits

.net - que - ¿Por qué el tamaño máximo del byte[] 2 GB-57 B?



que es un gigabyte (2)

Necesitas 56 bytes de sobrecarga. En realidad, es 2,147,483,649-1 menos 56 para el tamaño máximo. Es por eso que tu menos 57 trabaja y menos 56 no.

Como dice Jon Skeet aquí:

Sin embargo, en términos prácticos, no creo que ninguna implementación admita matrices tan grandes. El CLR tiene un límite por objeto un poco inferior a 2 GB, por lo que incluso una matriz de bytes no puede tener realmente 2147483648 elementos. Un poco de experimentación muestra que en mi caja, la matriz más grande que puedes crear es el byte nuevo [2147483591]. (Eso es en el .NET CLR de 64 bits; la versión de Mono que tengo instalado se ahoga en eso).

Véase también este artículo de InformIT sobre el mismo tema. Proporciona el siguiente código para demostrar los tamaños máximos y los gastos generales:

class Program { static void Main(string[] args) { AllocateMaxSize<byte>(); AllocateMaxSize<short>(); AllocateMaxSize<int>(); AllocateMaxSize<long>(); AllocateMaxSize<object>(); } const long twogigLimit = ((long)2 * 1024 * 1024 * 1024) - 1; static void AllocateMaxSize<T>() { int twogig = (int)twogigLimit; int num; Type tt = typeof(T); if (tt.IsValueType) { num = twogig / Marshal.SizeOf(typeof(T)); } else { num = twogig / IntPtr.Size; } T[] buff; bool success = false; do { try { buff = new T[num]; success = true; } catch (OutOfMemoryException) { --num; } } while (!success); Console.WriteLine("Maximum size of {0}[] is {1:N0} items.", typeof(T).ToString(), num); } }

Finalmente, el artículo tiene esto que decir:

Si hace los cálculos, verá que la sobrecarga para asignar una matriz es de 56 bytes. Quedan algunos bytes al final debido a los tamaños de los objetos. Por ejemplo, 268,435,448 números de 64 bits ocupan 2,147,483,584 bytes. Agregar la sobrecarga de la matriz de 56 bytes le otorga 2,147,483,640, lo que le deja 7 bytes menos que 2 gigabytes.

Editar:

¡Pero espera hay mas!

Mirando a su alrededor y hablando con Jon Skeet, me señaló un artículo que escribió sobre De memoria y cuerdas . En ese artículo proporciona una tabla de tamaños:

Type x86 size x64 size object 12 24 object[] 16 + length * 4 32 + length * 8 int[] 12 + length * 4 28 + length * 4 byte[] 12 + length 24 + length string 14 + length * 2 26 + length * 2

El Sr. Skeet continúa diciendo:

Se le podría perdonar por mirar los números de arriba y pensar que la "sobrecarga" de un objeto es de 12 bytes en x86 y 24 en x64 ... pero eso no es del todo correcto.

y esto:

  • Hay una sobrecarga "base" de 8 bytes por objeto en x86 y 16 por objeto en x64 ... dado que podemos almacenar un Int32 de datos "reales" en x86 y aún tener un tamaño de objeto de 12, y de igual manera podemos almacenar dos Int32s de datos reales en x64 y todavía tienen un objeto de x64.

  • Hay un tamaño "mínimo" de 12 bytes y 24 bytes respectivamente. En otras palabras, no puede tener un tipo que sea solo la sobrecarga. Tenga en cuenta que la clase "Vacío" ocupa el mismo tamaño que la creación de instancias de Objeto ... efectivamente hay espacio libre, porque al CLR no le gusta operar en un objeto sin datos. (Tenga en cuenta que una estructura sin campos también ocupa espacio, incluso para las variables locales).

  • Los objetos x86 se rellenan con límites de 4 bytes; en x64 son 8 bytes (como antes)

y finalmente Jon Skeet respondió a una pregunta que le hice en otra pregunta donde dice (en respuesta al artículo de InformIT que le mostré):

Parece que el artículo al que se está refiriendo está inferiendo la sobrecarga solo desde el límite, lo cual es una OMI tonta .

Entonces, para responder a su pregunta, la sobrecarga real es de 24 bytes con 32 bytes de espacio libre, de lo que recojo.

En mi máquina de 64 bits, este código C # funciona:

new byte[2L * 1024 * 1024 * 1024 - 57]

pero este lanza una OutOfMemoryException :

new byte[2L * 1024 * 1024 * 1024 - 56]

¿Por qué?

Entiendo que el tamaño máximo de un objeto administrado es de 2 GB y que el objeto de matriz que estoy creando contiene más de los bytes que quiero. Es decir, hay 4 bytes (o 8?) Para el número de bloque de sincronización, 8 bytes para la referencia de la tabla de métodos y 4 bytes para el tamaño de la matriz. Eso es 24 bytes, incluido el relleno, ¿por qué no puedo asignar una matriz con 2G - 24 bytes? ¿El tamaño máximo es realmente exactamente 2 GB? Si ese es el caso, ¿para qué se utiliza el resto de 2 GB?

Nota: en realidad no necesito asignar una matriz con 2 millones de bytes. E incluso si lo hiciera, 56 bytes es una sobrecarga insignificante. Y fácilmente podría evitar el límite utilizando BigArray<T> .


Una cosa es segura es que no puede tener un número impar de bytes, por lo general está en múltiplos del tamaño de la palabra nativa, que es de 8 bytes en un proceso de 64 bits. Así que podrías estar agregando otros 7 bytes a la matriz.