Windows Server
Escenario
- Failed to create a desktop due to desktop heap exhaustion
- Event ID 2019: “The server was unable to allocate from the system nonpaged pool because the pool was empty.”
En una arquitectura de 32 bits, la memoria virtual es un recurso medianamente escaso. No vamos a hablar de la cantidad memoria física del servidor. Si bien, mientras más memoria mejor, el problema a describir ahora no depende totalmente de la cantidad de memoria del servidor, ya que o bien tengas 2 o 20 GB, se presentará igual.
Con 32 bits, la memoria virtual, que tampoco tiene que ver con la memoria paginada en disco, está restringida a 4GB por aplicación. El valor 4GB se obtiene al elevar 2 a 32, o 2^32.
De esos 4 GB virtuales, 2 GB son usados por un proceso y los otros 2 por el kernel. Cada aplicación tendrá sus 2 GB virtuales y compartirán los 2 GB de kernel. Debido a esto último, algunos de ustedes recordarán haber visto en Task manager que un proceso nunca pasa de 1,7 o 1,8 GB. Bueno, la explicación es esa. Una aplicación no puede usar más de 2 GB de memoria virtual.
Existe un switch para que sí lo haga, pero con su consecuencia. Este switch se configura en el archivo boot.ini, y corresponde a la opción /3GB.
El impacto de la aplicación de éste es que del espacio virtual de 4 GB, 1 GB pasa de memoria de kernel a memoria de proceso de usuario. Entonces ahora un proceso de usuario puede llegar a usar 3 GB y el kernel queda drásticamente reducido a 1 GB.
SQL Server, Exchange, COM+ y los Application pool de IIS son algunos de los procesos que tomarán ventaja de este cambio y podrán llegar a 2,7 o 2,8 GB de memoria usada, lo que representa un incremento del 50%, y que tiende a ayudar bastante en algunos casos, pero en otros, produce problemas si no se usa adecuadamente.
¿El problema?
El kernel necesita memoria para poder funcionar, y 1 GB virtual no es suficiente en algunos casos. En el kernel se cargan drivers, el manejador de memoria, de procesos, controladores gráficos, el HAL, manejo de plug & play y otras tareas.
Además, el kernel maneja dos pool de memoria, uno llamado paginable y el otro no paginable. En ingles, paged pool y nonpaged pool respectivamente. ¿Recuerdan el evento 2019? Vuelvan a leer la descripción.
Al aplicar el switch /3GB, el tamaño de estos pools se reduce a la mitad, pudiendo entonces en determinados casos agotarse y poner en riesgo el servidor. Si el kernel no es capaz de obtener memoria de estos pools, varios problemas pueden ocurrir, a saber:- Problemas de interfaz grafica, en donde ésta no responde adecuadamente
- Problemas de funcionamiento de algunos procesos, para nuestro caso, las aplicaciones COM+ no levantan.
- Falla en procesar requerimientos vía red
Al aplicar /3GB se reduce también la cantidad de PTEs disponibles, lo que generará problemas con los requerimientos de IO, entre otros.
Identidades de aplicaciones
En las identidades de las aplicaciones COM+ cada aplicación que es iniciada con un usuario diferente, requerirá que el sistema operativo cargue ciertos componentes para el usuario (desktop). Estos componentes incluyen:- Menús del sistema
- Ventanas
- Otra información.
Entonces, si tengo aplicaciones COM+ configuradas con X usuarios, podría llegar a cargar X desktops. ¿De donde se obtiene la memoria para cargar estos desktops? De la memoria del kernel.
Link donde se explica la carga de Desktops http://blogs.msdn.com/ntdebugging/archive/2007/01/04/desktop-heap-overview.aspx.
Solución
Si tu aplicación no hará uso de 3GB, no incluyas la opción. No será necesaria.
Si tienes alguno de los servicios mencionados antes y necesitas usarlo, deberás entonces usar además la opción userva en el archivo boot.ini.
Userva se utiliza para “mover” un poco de memoria de proceso de usuario a kernel. Realmente no mueve nada, pero el efecto final es que en vez de tener 3GB de usuario y 1GB de kernel, puedes configurar 2,7 GB y 1,3GB respectivamente, lo que ayudará a mitigar el problema, y en la gran mayoría de los casos, desaparecerá totalmente.
El KB referenciado al final muestra como configurarlo. Si bien dice que se deberá probar entre 2900 y 3030, si es necesario para tu sistema, podrás llegar a un valor menor. Mayores valores no tienen sentido.
Si estas usando SQL Server, utiliza mejor AWE por sobre 3GB. No expondrás el kernel a estos problemas.
Adicionalmente, estos links te podrán proveer mas información: