c# .net memory-management 64bit

c# - Límite de memoria de proceso del proceso de 64 bits



.net memory-management (5)

Actualmente tengo una aplicación .Net de 32 bits (en Windows x86) que requiere mucha memoria. Recientemente comenzó a lanzar System.OutOfMemoryException''s.

Por lo tanto, estoy planeando moverlo a una plataforma x64 como proceso de 64 bits. Esto ayudará con las excepciones de falta de memoria. Estaba leyendo este artículo de MSDN Memory limits para Windows

Entonces, mi pregunta es: si compilo una aplicación .Net de 64 bits, ¿tendrá configurado IMAGE_FILE_LARGE_ADDRESS_AWARE como predeterminado (como lo sugiere el artículo)? es decir, ¿podré aprovechar el espacio de direcciones virtuales en modo de usuario de 8GB?


En realidad, en un SO x64 si su aplicación está compilada para AnyCPU, entonces no necesita hacer nada especial. El JIT creará una imagen x64 en tiempo de ejecución o una imagen x86 cuando se ejecute en un sistema de 32 bits.


En realidad, ese artículo establece que tendrá acceso a 8 TB de espacio de direcciones virtuales (y sí, esto es cierto).


Pasar a un bit de 64 bits definitivamente ayuda a recortar OutOfMemoryExceptions, pero es posible que desee centrarse en la arquitectura del sistema y los mecanismos de codificación para evitarlos, ya que solo sería cuestión de tiempo antes de que aparezcan en la máquina de 64 bits también.
Una ventaja más de pasar a máquinas de 64 bits es que con un espacio de direcciones virtuales de 8 TB, la recolección de basura para .NET ocurre con poca frecuencia. Esto mejora el rendimiento de las aplicaciones al aumentar el espacio virtual disponible para su programa.


El límite máximo de memoria para los procesos x64 es de 8 TB, pero el límite práctico es mucho menor, ya que depende de la cantidad de memoria física y el tamaño del archivo de paginación en el sistema. Vea esta publicación para más detalles sobre esto.

IMAGE_FILE_LARGE_ADDRESS_AWARE afecta a un proceso x86 que se ejecuta en un sistema operativo x64 (o un sistema operativo x86 con la directiva / 3GB). Su aplicación x64 no necesita configurar el indicador de dirección grande y podrá usar toda la memoria virtual disponible en su sistema.


IMAGE_FILE_LARGE_ADDRESS_AWARE solo es relevante para procesos de 32 bits. La razón es que el espacio de direcciones en Windows de 32 bits se divide en dos: 2 GB para el espacio del kernel y 2 GB para el espacio del usuario. Para abordar 2 GB necesita 31 bits. Es decir, los punteros en una aplicación de 32 bits no necesitan el último bit para direccionar.

Algunas aplicaciones pueden haber usado este bit adicional para fines personalizados, por lo que si el administrador de memoria de Windows les entrega repentinamente una dirección real de 32 bits, no podrán manejar eso. Al habilitar el indicador IMAGE_FILE_LARGE_ADDRESS_AWARE , la aplicación básicamente le dice al sistema operativo que puede manejar todo el espacio direccionable de 32 bits.

Si ejecuta una aplicación IMAGE_FILE_LARGE_ADDRESS_AWARE en Windows de 32 bits, puede acceder a 3 GB. Si ejecuta la misma aplicación de 32 bits en Windows de 64 bits, el proceso realmente obtiene el espacio completo de direcciones de 4 GB.

Si ejecuta una aplicación de 64 bits en Windows de 64 bits, el espacio de direcciones del usuario es de 8 TB (con otros 8 TB reservados para el espacio de direcciones del kernel). Las aplicaciones .NET configuradas en AnyCPU serán automáticamente aplicaciones de 64 bits en x64, por lo que no tiene que hacer nada para direccionar la memoria adicional.

Tenga en cuenta, sin embargo, que el CLR impone un límite de 2 GB en un solo objeto, por lo que aunque su aplicación pueda usar mucha memoria, no puede crear una matriz de 2 TB, por ejemplo. Más información en esta pregunta: ¿ Objetos únicos todavía están limitados a 2 GB de tamaño en CLR 4.0?