2010-10-12 18 views
8

Necesito cargar grandes cantidades de mapas de bits en la memoria para visualizarlos en una aplicación WPF (usando .net 4.0). Donde me encuentro con problemas es cuando me acerco a unos 1.400 MB de memoria (lo obtengo de la lista de procesos en el administrador de tareas).WPF excepción de memoria insuficiente cuando se carga una gran cantidad de mapas de bits en una sola instancia de la aplicación. ¿Hay un límite?

Lo mismo sucede si la aplicación se ejecuta en una máquina con 4 GB de memoria o 6 GB (y algunas otras configuraciones que no tengo los detalles). Es fácil de probar al reducir las imágenes cargadas y cuando funciona en 1 máquina, entonces funciona en todas ellas, pero cuando falla en una, también lo hace en todas.

Cuando reduzco el conteo de imágenes y dejo que la aplicación se cargue sin causar la excepción de memoria, puedo ejecutar varias instancias de la aplicación (superando los 1.4 GB de la instancia única) sin el problema, por lo que parece ser una instancia límite o error por instancia de mi parte.

me carga las imágenes como un BitmapImage y se almacenan ya sea en un List<BitmapImage> o cargado en un List<byte[]> donde son posteriormente utilizados en un grupo de secuencias de capas (utilizando un Writeablebitmap) occurrs

El error cuando cargo las imágenes no están en uso. En el caso repetible, cargo 600 imágenes 640X640 más otras 200-300 imágenes más pequeñas que van de 100X100 a 200X200, aunque parece ser un conteo general de bits el problema.

Así que mis preguntas son:

* ¿Hay algunas de ellas construidas en tanto por límite de memoria de proceso en una situación como esta?

* ¿Existe una mejor técnica para cargar grandes cantidades de datos de imagen en la memoria?

Gracias, Brian

+1

¿Está ejecutando una aplicación de 32 o 64 bits y qué sistema operativo? –

+0

Estoy ejecutando Windows 7 de 64 bits y compilando para 'x86' - Nota Anteriormente puse 'cualquier CPU' pero x86 es el formato de compilación – Brian

Respuesta

11

Sí, hay un límite en las asignaciones de memoria por proceso. Una de las soluciones es hacer que su binario LARGEADDRESSAWARE consuma más memoria.

Consulte Out of memory? Easy ways to increase the memory available to your program, tiene una gran discusión sobre soluciones para esto.

+0

Gracias, esta solución resolvió el problema. Tenía el mismo límite de 1,4 GB que el artículo menciona. Ahora estoy cerca de 2GB sin ningún problema usando la configuración LARGEADDRESSAWARE. – Brian

3

a continuación pueden ser una causa, pero no estoy seguro de

problema no se trata de cargar gran cantidad que de los datos, sino porque CLR mantiene un montón grande para el objeto mayor que 85k de memoria y usted no tiene ningún control para liberar este gran montón.

y estos objetos se convirtieron en Long Lived y normalmente se desasignarán cuando Appdomain Unloads.

sugiero que trate de cargar imágenes más grandes en otro dominio de aplicación y use ese dominio para aplicar imágenes más grandes.

See this MSDN Entry to Profiling GC

See if Memory Mapped Files helps in case you are using .net 4.0

And more example

+0

Estoy de acuerdo. Parece un problema de fragmentación de la memoria. – Nayan

1

Una acumulación x86 puede acceder a 4 GB en Windows de 64 bits, por lo que es el límite superior teórico para el proceso. Esto requiere que la aplicación sea large address aware. Además .NET impone un límite de 2 GB en un solo objeto.

Es posible que sufra la fragmentación de LOH. Los objetos de más de 85000 bytes se almacenan en el Gran montón de objetos, que es una parte especial del montón administrado que no se compacta.

Usted dice que las imágenes son 600x600, pero ¿cuál es el formato de píxel y hay una máscara también?Si usa un byte por canal de color más un byte para el canal alfa, cada imagen es de 600x600x32, por lo que intentar cargar 600 de ellas a la vez será un problema en un proceso de 32 bits.

+1

Brian, ¿puede proporcionar algún enlace de MSDN que indique que ".NET impone un límite de 2 GB para un solo objeto"? ¡Gracias! – Nayan

+0

Lo tengo. http://blogs.msdn.com/b/joshwil/archive/2005/08/10/450202.aspx – Nayan

+0

Pregunta relacionada http://stackoverflow.com/q/1087982/38206 –

0

Te encuentras con los procesos de limitación de 32 bits que solo pueden acceder a unos 2 Gb de datos. Si tuviera que ejecutar 64 bits, no tendría los problemas. Hay varias formas de solucionar el problema, algunas de las cuales son:

  • Simplemente no se cargan que, sólo cuando se necesitan muchos datos de carga. Use el almacenamiento en caché.
  • Utilice los archivos mapeados en la memoria para mapear toda la información en la memoria. No se recomienda, ya que tendrá que hacer toda la gestión de memoria usted mismo.
  • Use procesos múltiples para contener los datos y utilizar un mecanismo IPC para llevar sólo sobre los datos que necesita, de forma similar al punto 1.
Cuestiones relacionadas