2012-02-27 11 views
10

Estoy tratando de resolver algunas condiciones de poca memoria utilizando instrumentos. Puedo ver el consumo de memoria en el monitor de Physical Memory Free bajar a un par de MB, aunque las asignaciones muestran que All Allocations es de aproximadamente 3 MB y Bytes totales es de 34 MB.Uso de instrumentos para trabajar con advertencias de memoria baja

Empecé a experimentar bloqueos ya que moví algunas operaciones a una hebra separada con NSOperationQueue. Pero no estaba usando instrumentos antes del cambio. Sin embargo, estoy apostando a que hice algo que puedo deshacer para detener los bloqueos.

Por cierto, es mucho más estable sin instrumentos o sin el depurador conectado.

Tengo las fugas a casi ninguna (tal vez un máximo de cien bytes antes de un bloqueo).

Cuando miro las Asignaciones, solo veo objetos muy primitivos. Y la memoria total informada por ella también es muy baja. Así que no puedo ver cómo mi aplicación está causando estas advertencias de memoria baja.

Cuando miro Heap Shots desde el inicio, no veo más de 3 MB allí, entre la línea de base y la suma de todos los valores de crecimiento del montón.

¿Qué debería estar buscando para encontrar dónde está el problema? ¿Puedo aislarlo en una de las instancias de mi controlador de vista, por ejemplo? ¿O a una de mis otras instancias?

Lo que he hecho: Apagué y encendí el dispositivo, y esto mejoró significativamente. Instruments no informa una advertencia de memoria baja. Además, me di cuenta de que la memoria física gratuita en el inicio era de solo 7 MB antes de reiniciar, y es de unos 60 MB después de reiniciar.

Sin embargo, veo una caída muy regular (periódica) en la memoria física libre, bajando de 43 MB a 6 MB (y luego una copia de seguridad de hasta 43 MB). Me gustaría saber qué causa eso. No tengo cronómetros funcionando en esta aplicación. (Tengo algunos performSelector: afterDelay :, pero esos no están activos durante estas pruebas.)

No estoy usando ARC.

+0

¿Encontró una solución/explicación para esto? Tengo el mismo tipo de problemas. – mm24

Respuesta

2

Cuando estoy leyendo su texto, tengo la impresión de que podría tener algunas pérdidas ocultas. Podría estar equivocado pero, ¿estás 100% seguro de que has verificado todas las filtraciones?

Recuerdo un proyecto en particular que estaba haciendo hace unos meses, tenía el mismo tipo de problema y no tenía fugas en Instruments. Mi memoria creció y recibo advertencias de memoria ... Comienzo a iniciar sesión en algún método importante de dealloc. Y he visto que algunos objetos, subvistas (UIView) estaban "filtrando". Pero no fueron vistos por Instruments porque todavía estaban unidos a una vista principal.

Espero que haya sido útil.

9

La diferencia entre la memoria física de la máquina virtual Tracker y memoria asignada de "Asignaciones" es debido a las grandes diferencias de cómo estos instrumentos funcionan:

  • Asignacionesrastros lo que su aplicación hace mediante la instalación un toque en las funciones que asignan memoria (malloc, NSAllocateObject, ...). Este método proporciona información muy precisa sobre cada asignación, como posición en el código (pila), cantidad, tiempo, tipo.La desventaja es que si no rastrea cada función (como vm_allocate) que de alguna manera asigna memoria, perderá esta información.

  • VM Rastreadormuestras del estado de la memoria virtual del sistema en intervalos regulares. Este es un método mucho menos preciso, ya que solo proporciona una vista general del estado actual. Funciona a baja frecuencia (generalmente algo así como cada tres segundos) y no tiene idea de cómo se alcanzó este estado.

un culpable conocido de las asignaciones invisible es CoreGraphics: Se utiliza una gran cantidad de memoria al descomprimir imágenes, dibujo contextos de mapa de bits y similares. Esta memoria generalmente es invisible en el instrumento Allocations. Por lo tanto, si su aplicación maneja muchas imágenes, es probable que vea una gran diferencia entre la cantidad de memoria física y el tamaño total asignado.

Los picos en la memoria física pueden deberse a que las imágenes grandes se descomprimen, se reducen y, a continuación, solo se utilizan en la resolución de pantalla en el contenido de algunas capas o vistas. Todo esto puede suceder automáticamente en UIKit sin que su código esté involucrado.

+0

Todavía no tengo claro cómo usar las herramientas para rastrear el problema de memoria, dado lo que ya he dicho que lo he intentado. VM muestra una línea plana, sin ninguna actividad que pueda correlacionar con los saltos regulares en la memoria física libre. Probé varios de los otros instrumentos (nada se llama "CoreGraphics" per se) y de nuevo no veo ninguna correlación con el pulso del uso de la memoria. Me gustaría vincularlo a un proceso, pero no sé si puedo o cómo hacerlo. - Por cierto, apagué los servicios de localización, y eso tampoco hizo ninguna diferencia significativa en el pulso. – Jim

2

En el Instrumento de asignaciones, asegúrese de que ha marcado "Solo seguimiento de asignaciones activas". Ver imagen a continuación. Creo que esto hace que sea más fácil ver lo que está sucediendo realmente.

enter image description here

2
  1. ¿Se ha quedado Analizar en el proyecto? Si hay advertencias de análisis, corrígelas primero.

  2. ¿Estás utilizando alguna herramienta de CoreFoundation? Algunos de los métodos de CF tienen ... interacciones ... extrañas con el tiempo de ejecución ObjC y la gestión de mem (no deberían hacerlo, AFAICS, pero he visto un comportamiento extraño con la imagen de bajo nivel y las manipulaciones de AV donde parece como mem está siendo utilizado fuera del proceso de aplicación núcleo - tal vez el sistema operativo llamadas que son utilizados por Apple)

... NB: también tienen, en las versiones anteriores de iOS, estado unos MEM-fugas en el interior? Los métodos de CF de Apple. IIRC el último de esos fue arreglado en iOS 5.0.

  1. (analizador de Stackoverflow chupa: escribimos "3" no "1") ¿Estás haciendo algo con un gran número de/los casos de gran tamaño CALayer (o UIView de con CG métodos *, por ejemplo, un método drawRect costumbre en un UIView)

... NB:? he visto el comportamiento exacto usted describe causados ​​por 2 y 3 anteriores, ya sea en las bibliotecas CF, o en el sistema de ventanas de Apple cuando se trata de trabajar con los datos de imagen que se generaron originalmente dentro de las bibliotecas CF o que llegaron a CALayers.

Parece que Instruments NO SIGUE CORRECTAMENTE el uso de memoria dentro del sistema CA/CG; esta área es un poco compleja ya que Apple se mueve hacia adelante y hacia atrás entre CPU y GPU RAM, pero es decepcionante que el uso de la memoria simplemente "desaparezca" cuando todavía está siendo utilizado.


Pensamiento final (4. - pero SO no me deja escribir eso) - ¿está utilizando el invisible RHS of Instruments?

Apple codificó los instrumentos para deshabilitarse siempre cada vez que lo ejecuta (por lo que debe seguir abriendo manualmente). Esto es estúpido, ya que parte de la información del núcleo solo existe en la barra RHS. Pero he trabajado con varias personas que ni siquiera sabía que existía :)

19

Las asignaciones y las fugas instrumentos sólo se muestran cuáles son los objetos en realidad toman, pero no lo que sus estructuras no objeto subyacente (las tiendas de respaldo) están tomando. Por ejemplo, para UIImages mostrará que tienes algunos bytes asignados. Esto se debe a que un objeto UIImage solo toma esos bytes, pero el CGImageRef que en realidad contiene los datos de la imagen no es un objeto, y no se tiene en cuenta en estos instrumentos.

Si no lo está haciendo aún, intente ejecutar VM Tracker al mismo tiempo que ejecuta el instrumento de asignaciones. Le dará una idea de la memoria de tipo que se está asignando. Para iOS, "Dirty Memory", que se muestra en este instrumento, es lo que normalmente activa las advertencias de memoria. La memoria sucia es una memoria que no puede ser descartada automáticamente por el sistema VM. Si ve muchas imágenes CG, las imágenes pueden ser su problema.

Otro concepto importante es memoria abandonada. Esta es la memoria que se asignó, todavía se hace referencia en algún lugar (y como tal, no es una fuga), pero no se utiliza. Un ejemplo de este tipo de memoria es un caché de algún tipo, que no se libera al recibir una advertencia de memoria. Una forma de descubrir esto es usar el análisis de montón. Presione el botón "Mark Heap" del instrumento de asignaciones, realice alguna operación, regrese al punto anterior en la aplicación y presione "Mark Heap" nuevamente. La segunda foto de pila debería mostrar qué objetos nuevos se han asignado entre esos dos momentos y podría arrojar algo de luz sobre el misterio. También podría repetir la operación simulando una advertencia de memoria para ver si ese comportamiento cambia.

Finalmente, le recomiendo que lea este artículo, que explica cómo funciona todo esto: http://liam.flookes.com/wp/2012/05/03/finding-ios-memory/.

4

Tengo las fugas a casi ninguna (quizás un máximo de cien bytes antes de un bloqueo).

En mi experiencia, también las fugas muy pequeñas son señales "peligrosas". De hecho, nunca he visto una fuga mayor a 4K, y las filtraciones que generalmente veo son un par de cientos de bytes. Aún así, generalmente "esconden" detrás de ellos una memoria mucho más grande que se pierde.

Por lo tanto, mi primera sugerencia es: deshacerse de esas fugas, a pesar de que parecen pequeñas e insignificantes, no lo son.

Empecé a experimentar bloqueos ya que moví algunas operaciones a una hebra separada con NSOperationQueue.

¿Hay alguna posibilidad de que la operación que mueva al hilo sea la responsable del pico pulsante? ¿Podría generarse más de una vez a la vez?

En cuanto a los picos, veo dos formas en que puede ir sobre ellos:

  1. utilizar el Analizador de tiempo en Instrumentos y tratar de entender lo que el código se ejecuta mientras se ve el pico de aumento;

  2. comente selectivamente partes de su código (me refiero a partes completas de su aplicación, por ejemplo, reemplace un controlador "real" con un UIViewController básico/vacío, etc.) y vea si puede identificar al culpable de esta manera .

Nunca he visto un comportamiento tan pulsátil, por lo que supongo que depende de su aplicación o de su dispositivo. ¿Has probado con un dispositivo diferente? ¿Qué sucede en el simulador (ves el pico)?

Cuestiones relacionadas