Consumo de memoria de las imágenes
Las imágenes en .net se guardan como Bitmap, única herencia de Image (la otra es Metafile). Como nosotros tenemos propiedades de imágenes en las entidades, mientras una entidad está cargada se mantienen en memoria sus imágenes. No se cargan con la entidad, sólo cuando se necesitan, pero una vez cargadas ya se mantienen con la entidad. Al hojear el Catálogo comercial de N2 Frax, se carga una colección con los 130 artículos del catálogo, y si vamos pasando las páginas una a una al llegar a la 30 tenemos en uso 500 Mb de memoria RAM, y Windows se vuelve loco usando memoria virtual, el sistema prácticamente se congela.
Las imágenes de este catálogo son mucho más grandes que temporadas anteriores (se han sacado con máxima calidad), lo que ha agravado el problema. Aunque sean archivos png de unos 70 Kb, en memoria se guardan como Bitmap, por lo que el uso de memoria es tremendo.
He encontrado pocas historias parecidas en Internet. Un tío dice que le falla en ASP, pero nadie le contesta. Hay pocas referencias a la cuestión de cachear imágenes en memoria. Un colega cuenta su experiencia desarrollando una caché de imágenes que libera imágenes cuando supera un número de Kb en memoria.
Así que vemos la necesidad de limitar el número de imágenes almacenadas en memoria, para lo que deben almacenarse en un lugar centralizado: CentroImagenes, en vez de variables privadas en las entidades. Así puede controlarse el volumen de memoria utilizado, y liberar cuando se alcance una cantidad que podrá parametrizarse.
Surge un problema: cuando asignamos una imagen a una entidad, no debe guardarse en disco hasta guardar la entidad. Así que creamos nuevos métodos en CentroImagenes:
- Preasignar(clave, imagen) para incluir la imagen en caché pero no en disco. Debe llamarse en el set de la propiedad imagen de la entidad.
- Confirmar(clave) para guardar en disco una imagen que ya hemos preasignado en caché. Debe llamarse al guardar la entidad.
- Descartar(clave) para quitar de caché una imagen que hemos preasignado antes. Debe llamarse en el deshacer de la entidad.
Con esto nunca se almacena una imagen en negocio, sino que todas se centralizan en CentroImagenes, y así podemos liberar a voluntad... aunque hay que intentar no liberar una imagen preasignada (si no cuando se intente guardar su entidad se habrá perdido la imagen que asignó el usuario).
Para liberar, vamos a consultar el consumo en memoria, pero no encuentro cómo consultar cuanta memoria ocupa la caché, o cuanta ocupa cada imagen, así que habrá que estimarla: al incluir cada imagen, calcularemos su número de pixeles y supondremos que cada uno ocupa 4 bytes (lo he leído en algún sitio). Habrá que descontar también cuando quitemos imágenes de la caché.
Etiquetas: Imagenes, Nibi.Negocio
