6

Mi aplicación, que utiliza ARC, hace lo siguiente:La reducción de la memoria de UIImages de la cámara utilizando instrumentos

  1. carga una imagen tomada por la cámara
  2. comprime la imagen para su uso como una miniatura.
  3. hago esto utilizando [UIImage imageWithData: UIImageJPEGRepresentation (original, 0.1f)]
  4. I establezca la referencia de la imagen sin comprimir a cero para ARC para liberar la memoria

Repitiendo esta secuencia significará que varios comprimidos las miniaturas están en la pantalla. Después de aproximadamente 7 u 8 imágenes, la aplicación se bloqueará debido a la poca memoria.

En Instruments, estoy intentando usar asignaciones en tándem con Memory Monitor para encontrar el origen de mi problema.

Algunas estadísticas Instrumentos:

asignación - Vivo Bytes salta por cerca de 2 MB después de tomar una foto, pero luego va disminuyendo en 1,5 MB después de la referencia de la imagen original se establece en cero. Eso parece ser algo bueno, pero ...

Aquí hay un estado final de la aplicación. # La vida parece ser muy alta en relación con los Live Bytes, ¿verdad?

Live Bytes #Living #Transitory Overall #Overall Bytes  
    3.72 MB 24538  80679  90.1 MB 105301 

Memory Monitor (seguimiento de cabezal de inspección) - Mi aplicación se inicia en el 7,5 MB y tomando uno resultados de imagen en la que el aumento de ~ 13 MB. Para el estado que he enumerado anteriormente, el monitor de memoria dice que la aplicación está ocupando 72.67 MB de "memoria real" y 123.79 MB de memoria virtual.

Teniendo en cuenta que los Live Bytes son muy pequeños, sé que estoy haciendo algo bien, . Sin embargo, dado que la huella de memoria en otros lugares es grande, también estoy seguro de que estoy haciendo algo muy mal. ¿Alguna idea de lo que podría ser, o cómo rastrearla?

+0

+1 para una buena pregunta. ¿Cómo está cargando sus imágenes para mostrarlas en la pantalla? ¿Estás usando '[UIImage imageNamed:]'? – Rog

+1

Dijo que usa la cámara. –

+0

¿Cuál es el propósito de esta línea? [UIImage imageWithData: UIImageJPEGRepresentation (original, 0.1f)] Está comprimiendo la imagen y luego descomprimiéndola inmediatamente. El resultado es solo una pérdida de calidad de imagen y tiempo de CPU. –

Respuesta

2

Eitan27,

Esto no es un problema de ARC. Se trata de cómo administrar múltiples elementos grandes en la memoria. iOS tiene varios mecanismos para ayudarte aquí. Si escribe la imagen para flashearla y luego la vuelve a abrir como datos mapeados en memoria, en su mayoría resolverá su problema. ¿Cómo? El SO gestiona el mapeo en su huella de memoria residente con datos inmutables. Como estos elementos son inmutables y, por lo tanto, nunca sucios, pueden limpiar las páginas asignadas cuando sea necesario. La desventaja de este mecanismo es la cantidad limitada de descriptores de archivos disponibles para cada aplicación.

Andrew

+0

Gracias adonoho. Tu respuesta suena genial, aunque mencionas algunas cosas con las que no estoy familiarizado. ¿Por qué hay un límite en los descriptores de archivos? Al guardar en flash, ¿quiere decir escribir/recuperarlo del disco usando un nombre de archivo? ¿O está sugiriendo más o menos que implemente algo similar a TileView/CATileLayer? – Eitan

+0

Eitan27, cada aplicación tiene un número limitado de archivos que puede tener abiertos en cualquier momento. El descriptor de archivo es la estructura de datos racionada por el sistema operativo. Por lo general, solo tienes 30 o más de estos disponibles. Por flash, me refiero a su almacenamiento persistente. Como estás teniendo este problema de espacio, supuse que estabas corriendo en iOS. Todos los dispositivos iOS usan memoria RAM flash como almacenamiento persistente. Andrew P.S. No olvide premiar a las personas que responden a sus preguntas con la gran marca de verificación verde. – adonoho

+0

Absolutamente, y sí, me estoy ejecutando en iOS. No estaba claro si el límite del descriptor de archivo se encuentra en el total de archivos o si los archivos están abiertos en un momento determinado. Parece que es el último y que el problema se resolverá mediante el uso de CATileLayer para abrir/mostrar imágenes solo cuando se necesiten. – Eitan

0

utilizar un bloque de @autoreleasepool:

@autoreleasepool { 
    //code that inits the UIImage and sets it to nil 
} 

Ver ARC proporciona una nueva Norma para Manejo de Autorelease piscinas sección del Transitioning to ARC Release Notes

+0

No estoy seguro de que esto se aplique a mí. La imagen se asigna, y luego una instancia de mi clase de carga se le da una referencia a la imagen y la carga. El cargador entonces establece su referencia a nil. Por lo tanto, el "init" de la imagen y el "lo pone a cero" ocurren en dos lugares diferentes. – Eitan

Cuestiones relacionadas