Pregunta

Nuestro servicio tiende a quedarse dormido durante las noches en el servidor de nuestro cliente, y luego tiene dificultades para despertarse. Lo que parece suceder es que el montón de proceso, que a veces es de varios cientos de MB, se mueve al archivo de intercambio. Esto sucede por la noche, cuando nuestro servicio no se usa y otros están programados para ejecutarse (copias de seguridad de bases de datos, escaneos AV, etc.). Cuando esto sucede, después de algunas horas de inactividad, la primera llamada al servicio demora unos minutos (las llamadas posteriores tardan segundos).

Estoy bastante seguro de que es un problema de administración de memoria virtual, y realmente odio la idea de obligar al sistema operativo a mantener nuestro servicio en la memoria física. Sé que hacer eso dañará otros procesos en el servidor y disminuirá el rendimiento general del servidor. Dicho esto, nuestros clientes solo quieren que nuestra aplicación sea receptiva. No les importa si los trabajos nocturnos tardan más.

Recuerdo vagamente que hay una manera de obligar a Windows a mantener las páginas en la memoria física, pero realmente odio esa idea. Me estoy inclinando más hacia algún perro guardián interno o externo que iniciará funcionalidades de nivel superior (ya hay algún programador interno que hace muy poco y no hace ninguna diferencia). Si hubiera una herramienta de terceros que proporcionara ese tipo de servicio, habría sido igual de bueno.

Me encantaría escuchar cualquier comentario, recomendación y solución común para este tipo de problema. El servicio está escrito en VC2005 y se ejecuta en servidores Windows.

¿Fue útil?

Solución

Como mencionó, obligar a la aplicación a permanecer en la memoria no es la mejor manera de compartir recursos en la máquina. Una solución rápida que puede encontrar que funciona bien es simplemente programar un evento que despierte su servicio a una hora específica cada mañana antes de que sus clientes comiencen a usarlo. Puede programarlo en el programador de tareas de Windows con un script simple o una llamada EXE.

Otros consejos

No estoy diciendo que quieras hacer esto, o que es la mejor práctica, pero es posible que te funcione lo suficientemente bien. Parece coincidir con lo que has pedido.

Resumen: toque cada página del proceso, página por página, de forma regular.

¿Qué pasa con un hilo que se ejecuta en segundo plano y se activa una vez cada N segundos? Cada vez que la página se activa, intenta leer desde la dirección X. El intento está protegido con un controlador de excepciones en caso de que lea una dirección incorrecta. Luego incremente X en el tamaño de una página.

Hay 65536 páginas en 4GB, 49152 páginas en 3GB, 32768 páginas en 2GB. Divida su tiempo de inactividad (tiempo muerto durante la noche) por la frecuencia con la que desea (intente) llegar a cada página.

BYTE *ptr;

ptr = NULL;
while(TRUE)
{
    __try
    {
        BYTE b;

        b = *ptr;
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        // ignore, some pages won't be accessible
    }

    ptr += sizeofVMPage;

    Sleep(N * 1000);
}

Puede obtener el valor sizeOfVMPage del valor dwPageSize en el resultado devuelto por GetSystemInfo ().

No intente evitar el controlador de excepciones utilizando if (! IsBadReadPtr (ptr)) porque otros subprocesos de la aplicación pueden estar modificando las protecciones de memoria al mismo tiempo. Si se despega debido a esto, será casi imposible identificar por qué (lo más probable es que sea una condición de carrera no repetible), así que no pierda el tiempo con eso.

Por supuesto, querrás desactivar este hilo durante el día y solo ejecutarlo durante tu tiempo muerto.

Un tercer enfoque podría ser hacer que su servicio ejecute un hilo que haga algo trivial como incrementar un contador y luego duerma durante un período bastante largo, digamos 10 segundos. Thios debería tener un efecto mínimo en otras aplicaciones, pero mantener al menos algunas de sus páginas disponibles.

La otra cosa que debe asegurarse es que sus datos estén localizados.

En otras palabras: ¿realmente necesita los 300 MiB de la memoria antes de poder hacer algo? ¿Se pueden reorganizar las estructuras de datos que utiliza para que cualquier solicitud en particular pueda satisfacerse con solo unos pocos megabytes?

Por ejemplo

  • si sus 300 MiB de memoria de almacenamiento dinámico contienen datos de reconocimiento facial. ¿Se pueden organizar los datos internamente de modo que los datos de rostro masculino y femenino se almacenen juntos? ¿O los grandes noes están separados de las pequeñas narices?

  • si tiene algún tipo de estructura lógica, ¿se puede ordenar? para que una búsqueda binaria se pueda utilizar para saltar muchas páginas?

  • si se trata de un motor de base de datos propio, en memoria, ¿se pueden indexar / agrupar mejor los datos para no requerir tantos accesos a la página de memoria?

  • si son texturas de imágenes, ¿pueden las texturas de uso común ubicarse una cerca de la otra?

¿Realmente necesitas los 300 MiB de memoria antes de poder hacer algo? ¿No puede atender la solicitud sin todos esos datos nuevamente en la memoria?


De lo contrario: tarea programada a las 6 ?? para activarla.

En términos de costo, la solución más barata y fácil es probablemente comprar más RAM para ese servidor, y luego puede deshabilitar por completo el archivo de página. Si está ejecutando Windows de 32 bits, simplemente compre 4 GB de RAM. Luego, todo el espacio de direcciones estará respaldado con memoria física, y el archivo de página no hará nada de todos modos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top