tengo - Comprender el consumo de memoria en iPhone
liberar espacio sistema iphone (5)
Esto no lo ayuda específicamente, pero si encuentra que las herramientas de memoria no proporcionan todos los datos que necesita, presente un error en bugreport.apple.com. Adjunte una copia de su aplicación y una descripción de cómo las herramientas no alcanzan su análisis y Apple verá si pueden mejorar las herramientas. ¡Gracias!
Estoy trabajando en un juego de iPhone en 2D con OpenGL ES y sigo llegando al límite de memoria de 24 MB: mi aplicación sigue fallando con el código de error 101. Intenté realmente encontrar dónde va la memoria, pero los números en Instrumentos todavía son mucho más grande de lo que esperaría.
Ejecuté la aplicación con los instrumentos Memory Monitor, Object Alloc, Leaks y OpenGL ES. Cuando la aplicación se carga, la memoria física libre baja de 37 MB a 23 MB, el Object Alloc se instala alrededor de 7 MB, las filtraciones muestran dos o tres filtraciones de unos pocos bytes, el tamaño del objeto Gart es de aproximadamente 5 MB y el monitor de memoria dice la aplicación ocupa alrededor de 14 MB de memoria real. Estoy perplejo como a dónde fue la memoria: cuando profundizo en las asignaciones de objetos, la mayor parte de la memoria está en las texturas, exactamente como era de esperar. Pero tanto mi propio contador de asignación de textura como el Tamaño de objeto de Gart coinciden en que las texturas deberían ocupar alrededor de 5 MB.
No estoy al tanto de asignar nada más que merezca la pena mencionar, y el Object Alloc está de acuerdo. ¿A dónde va la memoria? (Me gustaría proporcionar más detalles si esto no es suficiente).
Actualización: realmente traté de encontrar dónde podía asignar tanta memoria, pero sin resultados. Lo que me vuelve loco es la diferencia entre las asignaciones de objetos (~ 7 MB) y el uso real de la memoria como se muestra en el monitor de la memoria (~ 14 MB). Incluso si hubiera grandes filtraciones o grandes trozos de memoria que me olvidé, aún deberían aparecer en las Asignaciones de Objetos , ¿no es así?
Ya he probado los suspects usual , es decir. el UIImage
con su almacenamiento en caché, pero eso no ayudó. ¿Hay alguna manera de rastrear el uso de la memoria "depurador-estilo", línea por línea, viendo el impacto de cada declaración en el uso de la memoria?
Lo que he encontrado hasta ahora
Realmente estoy usando tanta memoria. No es fácil medir el consumo real de memoria, pero después de un montón de conteos, creo que el consumo de memoria es realmente tan alto. Mi culpa.
No encontré una manera fácil de medir la memoria utilizada. Los números del Monitor de memoria son precisos (estos son los números que realmente importan), pero el Monitor de memoria no puede decirle dónde va exactamente la memoria. La herramienta Object Alloc es casi inútil para rastrear el uso real de la memoria. Cuando creo una textura, el contador de memoria asignada se sube por un tiempo (leyendo la textura en la memoria), luego se cae (pasando los datos de textura a OpenGL, liberando). Esto está bien, pero no siempre ocurre, a veces el uso de la memoria se mantiene alto incluso después de que la textura se transfiere a OpenGL y se libera de la memoria "my". Esto significa que la cantidad total de memoria asignada como se muestra en la herramienta Object Alloc es menor que el consumo de memoria total real, pero mayor que el consumo real menos texturas (
real – textures < object alloc < real
). Imagínate.Leí mal la Guía de programación. El límite de memoria de 24 MB se aplica a texturas y superficies, no a toda la aplicación. La línea roja real se encuentra un poco más lejos, pero no pude encontrar ningún número difícil. El consenso es que 25-30 MB es el techo.
Cuando el sistema tiene poca memoria, comienza a enviar la advertencia de memoria. No tengo casi nada que liberar, pero otras aplicaciones liberan algo de memoria al sistema, especialmente a Safari (que parece almacenar en caché los sitios web). Cuando la memoria libre como se muestra en el Monitor de Memoria se pone a cero, el sistema comienza a matar.
Tuve que morder la bala y reescribir algunas partes del código para ser más eficiente en la memoria, pero probablemente todavía lo estoy presionando. Si tuviera que diseñar otro juego, ciertamente pensaría en una búsqueda de recursos. Con el juego actual es bastante difícil, porque la cosa está en movimiento todo el tiempo y cargar las texturas se pone en el camino, incluso si se hace en otro hilo. Estaría muy interesado en cómo otras personas resuelven este problema.
Tenga en cuenta que estos son solo mis puntos de vista que no tienen que ser muy precisos. Si encuentro algo más que decir sobre este tema, actualizaré la pregunta. Mantendré la pregunta abierta en caso de que alguien que entienda el problema cuide responder, ya que todos estos son más soluciones provisionales que cualquier otra cosa.
Hmm, no hay muchos detalles, pero si las filtraciones no muestran dónde están las fugas, hay dos opciones importantes:
[i] Las filtraciones perdieron una fuga [ii] La memoria en realidad no se está filtrando
arreglar [i] es bastante difícil, pero como dijo Eric Albert, presentar un informe de error con Apple ayudará. [ii] significa que la memoria que estás utilizando todavía está accesible en algún lado, pero quizás te hayas olvidado de ella. ¿Hay listas en crecimiento, sin tirar entradas antiguas? ¿Hay algún búfer realloc () ed mucho?
Para aquellos que ven esto después del año 2012:
La memoria realmente cargada en la memoria física del dispositivo es la memoria residente en el instrumento VM Tracker.
El instrumento de asignación solo marca la memoria creada por malloc / [NSObject alloc] y parte del buffer de la estructura, por ejemplo, el mapa de bits de la imagen descomprimida no se incluye en el instrumento de asignación pero siempre ocupa la mayor parte de la memoria.
Mire WWDC 2012 Session 242 iOS App Performance: Memory para obtener la información de Apple.
Una forma es comenzar a comentar el código y verificar si el error persiste. Sí, es tedioso y elemental, pero podría ser útil si supieras dónde estaba el error.
Donde está chocando es por qué está fallando, etc.
Dudo mucho que esto sea un error en Instruments.
Primero, lea esta publicación de blog de Jeff Lamarche sobre texturas OpenGL :
- tiene un ejemplo simple de cómo cargar texturas sin causar filtraciones
- da una idea de cómo las imágenes "pequeñas", una vez cargadas en OpenGL, realmente usan "mucha" memoria
Extracto:
Las texturas, incluso si están hechas de imágenes comprimidas, utilizan una gran cantidad del montón de memoria de la aplicación porque deben expandirse en la memoria para ser utilizadas. Cada píxel ocupa cuatro bytes, por lo que olvidarte de liberar los datos de tu imagen de textura puede realmente devorar tu memoria rápidamente.
En segundo lugar, es posible depurar la memoria de textura con Instruments. Hay dos configuraciones de perfil: OpenGL ES Analyzer y OpenGL ES Driver . Deberá ejecutarlos en el dispositivo, ya que el simulador no utiliza OpenGL. Simplemente elija Producto-> Perfil de XCode y busque estos perfiles una vez que se inicie Instruments.
Armado con ese conocimiento, esto es lo que haría:
- Compruebe que no está perdiendo memoria , esto obviamente causará este problema.
- Asegúrese de que no está accediendo a la memoria liberada automáticamente , causa común de fallas.
- Cree una aplicación de prueba por separado y juegue con cargar texturas individualmente (y en combinación) para descubrir qué textura (o combinación de las mismas) está causando el problema.
ACTUALIZACIÓN: Después de pensar en su pregunta, he estado leyendo la Guía de programación de OpenGL ES de Apple y tiene muy buena información. ¡Muy recomendable!