Una excepción de memoria fuera de memoria en una aplicación administrada que se ejecuta en el servidor de 64 .NET Framework
Este artículo le ayuda a resolver la excepción de memoria fuera de memoria cuando tiene una aplicación administrada dirigida a Microsoft .NET Framework de 64 bits 4.6.1.
Versión del producto original: .NET Framework 4.6.1
Número KB original: 3152158
Síntomas
Tiene una aplicación administrada dirigida a la aplicación de 64 bits .NET Framework 4.6.1. Esta aplicación produce una excepción de memoria fuera de la memoria de Common Language Runtime (CLR) con el siguiente mensaje específico:
OutOfMemoryException: "Memoria insuficiente dentro del intervalo de espacio de direcciones especificado para continuar con la ejecución del programa".
Causa
CLR propaga esta excepción fuera de memoria cuando el subsistema de administrador de código no puede asignar memoria dentro de un intervalo de espacio de direcciones específico para los códigos auxiliares de salto. (Estos códigos auxiliares de salto corresponden al método que llama entre bibliotecas de vínculos dinámicos (DLL) que se encuentran 2 GB o más separados en el espacio de direcciones). Debe haber espacio en un radio de 2 GB del método de llamada para almacenar el código auxiliar de salto de una llamada de método de 64 bits. No hay ninguna forma segura de que una aplicación se recupere de este error específico. Por lo tanto, el estado de la aplicación después de que cumpla este error es desconocido y debe considerarse dañado. La única forma de recuperar es reiniciar la aplicación.
Solución alternativa
Para evitar este problema, use uno de los siguientes métodos de configuración:
Implemente una configuración de todo el equipo agregando la siguiente clave del Registro:
- Ubicación:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework - Tipo: DWORD
- Nombre: NGenReserveForjumpStubs
- Valor: 00000005
- Ubicación:
Implemente una configuración de nivel de aplicación agregando la siguiente sección al archivo de configuración de la aplicación:
<configuration> <runtime> <NGenReserveForJumpStubs value="5" /> </runtime> </configuration>Nota
NGenReserveForJumpStubshace que CLR reserve un porcentaje del espacio de direcciones para los códigos auxiliares de salto cerca de cada imagen NGen cargada. Se recomienda usar un valor de 5 o superior si está experimentando esteOutOfMemoryException.
Información para desarrolladores
El .NET Framework codifica las llamadas al método como saltos relativos de 32 bits por motivos de rendimiento. En un sistema de 64 bits, la persona que llama y llama puede tener más de 2 GB (en el espacio de direcciones). Dado que supera el intervalo de direcciones de un desplazamiento de 32 bits firmado, .NET creará un código auxiliar de salto dentro de 2 GB del autor de la llamada. A continuación, este código auxiliar de salto puede realizar el salto largo a cualquier lugar del espacio de direcciones de 64 bits.
Las mitigaciones de JIT y NGen funcionan de forma ligeramente diferente. Ambos reservan espacio de direcciones adicional por adelantado, pero el punto donde se realiza esta reserva difiere entre los dos.
NGenReserveForJumpStubses un porcentaje del tamaño de imagen NGen virtual (percentReserveForJumpStubs).Un código auxiliar de salto típico es de 12 bytes. Para obtener más información, vea JUMP_ALLOCATE_SIZE.
La memoria se asigna y se reserva cerca de la dirección donde se cargó la imagen NGen (el algoritmo exacto es EEJitManager::EnsureJumpStubReserve. La memoria se confirma cuando es necesario asignar un código auxiliar de salto y cuando no hay otro espacio de direcciones adecuado disponible.
La mitigación mencionada anteriormente no modifica el contenido de las imágenes de NGen. Las imágenes NGen tienen la misma superficie de disco con y sin mitigación.
Actualmente no hay una buena forma de detectar cuándo la aplicación se acerca al límite. Puede supervisar el para determinar
OutOfMemoryExceptionsi el espacio reservado es suficiente.Es posible que reciba la memoria incluso si hay mucha memoria sin usar porque este error específico está relacionado con la disponibilidad de memoria dentro de un radio de intervalo de direcciones de 2 GB del autor de
OutOfMemoryExceptionla llamada.No cambie el valor predeterminado de , porque puede que
CodeHeapReserveForJumpStubsno esté relacionado con el problema descrito anteriormente. No hemos visto casos en los que la aplicación real tendría que ajustar esta configuración como solución alternativa.Establecer en un valor más alto puede provocar un rendimiento reducido y el riesgo
NGenReserveForJumpStubsde exponer otros problemas sutiles.
Información para usuarios de TI
- Este problema también puede producirse en otras versiones del .NET Framework. Sin embargo, la solución alternativa actualmente solo se aplica al .NET Framework 4.6.1.
- Es un problema poco común que solo afecta a cargas de trabajo grandes que tienen un patrón de ejecución determinado. Más del 99 % de todas las cargas de trabajo experimentarán este problema.
- Después de que la aplicación inicia
OutOfMemoryExceptionun , la única forma recomendada de recuperar es reiniciar la aplicación.