lunes, julio 13, 2009

Workarounds o Ñapas

Aunque de toda la vida por estos lares se las ha llamado ñapas (chapucillas, apaños, arreglos), el término en ingles, workaround, pronunciado guorc-arraaummmm, queda más fino por aquello de la internacionalidad multilingüe.

Bien, como comentaba el otro día, en unos servidores del curro teníamos unos 'ligeros' problemas de memoria: El kernel no liberaba la memoria cache que utilizaba para uso propio, utilizando memoria de intercambio (muy costosa en uso por los tiempos de acceso) para los procesos. Pasado un tiempo, el sistema había consumido casi toda la memoria de intercambio, manteniendo ingentes cantidades de memoria cache, con el consiguiente problema de incremente de la entrada/salida y lentitud del sistema producto de los procesos de escritura en disco de la memoria swap.

La solución buena es compilar un kernel de una versión superior que no presente ese error, puesto que no existe un bugfix disponible. La solución 'workarround' es otra: Quitar la memoria de intercambio.

De esa forma, el kernel se ve obligado, cuando no tiene memoria libre, a liberar por cojones la memoria cache que el tan graciosamente se ha apropiado. Con un rápido 'swapoff -a', la memoria de intercambio pasa a la historia. Hice un programa, a modo de prueba de concepto, que consumía memoria a raudales (300 MB por instancia del mismo), lo lance en varias ejecuciones (10 simultaneamente, total 3 GB). Esto hizo, que el kernel entregara memoria cache para los programas en ejecuciones. No tenia más remedio.

Y aqui esta el 'pogama', llamado malloc.

# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>

int main (int argc, char *argv[]) {
int i=0;
int *puntero = NULL;
printf ("Reservando memoria con malloc\n");

while (i < 100000) {
printf ("Reservando bloque [%d] de 10k int (%d bytes)\r", i,
sizeof(int));
if ((puntero = malloc(sizeof(int)*10240)) == NULL) {
printf ("Alcanzada memoria maxima disponible para un
proceso en bloque %d\n", i);
printf ("Se termina de reservar memoria para el
proceso\n");
break;
}
i++;
}

printf ("Pulse Ctrl+z para retener memoria\n");
printf ("Pulse Ctrl+c para terminar ejecucion y liberar memoria\n");
pause ();

return 0;
}

No hay comentarios:

Publicar un comentario