jueves, 22 de marzo de 2012

Detectar problemas de memoria con Instruments

En Objective-C, cuando se maneja la memoria "a mano" con retain/release/autorelease, es bastante común que aparezcan problemas de memoria.

Estos problemas no deberían aparecer si se usa ARC (Automatic Reference Counting) en el proyecto, ya que todo el manejo lo hace automáticamente el compilador.

Los problemas que pueden aparecer son de dos clases:
  • Leaks: un objeto se retiene más veces que las que se libera, por lo que queda memoria en uso, a la que no se puede acceder.
  • Zombies: un objeto que se libera más veces de las que se retiene, por lo que la aplicación da un error cuando se le intenta mandar un mensaje.
Los Zombies en general son más fáciles de detectar ejecutando la aplicación, porque la aplicación termina con un error. De todas formas, a partir del error, no siempre es fácil detectar donde se produce o por que.

Para ambos casos, Xcode viene con una aplicación llamada Instruments, que permite detectarlos.

Para poder ejecutar Instruments, se debe ejecutar la aplicación con "Profile" (en lugar de "Run"), lo que va a mostrar una pantalla como sigue:

En esta pantalla se elige que es lo que queremos buscar (Leaks o Zombies), y luego se abre la ventana de Instruments correspondiente y la aplicación en el Simulator.

Al ejecutar la aplicación, si aparece algún problema de memoria, se va a ver en esta ventana.

Por ejemplo, cuando tenemos "leaks":

En la parte superior de la pantalla, nos muestra en azul la memoria que va usando, y en rojo cuando aparece un "leak".

En la parte de abajo, muestra los objetos que no se liberaron. Ahí se puede ver la clase del objeto, quien fue la biblioteca responsable, y donde fue que se produjo el "leak". Si hacemos click en la flechita al lado de Address, entonces muestra toda la historia de ese objeto: cuando fue que se creo, cuando se retuvo y cuando se liberó. Eso permite tener una idea bastante clara de donde fue que se produjo el problema.

Si bien no nos da la ubicación exacta de donde está el problema (es decir, donde se debió haber liberado la memoria y no se hizo), da mucha información que permite encontrarlo de forma relativamente fácil.

Lo mismo ocurre con los "zombies", cuando la aplicación da un error de tipo "EX_BAD_ACCESS", es seguramente porque tenemos un objeto que se liberó de más.

Cuando corremos la aplicación con Instruments, si aparece un "zombie" muestra una cartel indicándolo, y si hacemos click en la flechita, muestra toda la historia del objeto, cuando se le hizo "retain" y "release", lo que permite encontrar de forma bastante rápida donde está el problema.


Con Instruments se pueden hacer muchas más cosas. Estas dos tal vez sean las más comunes, pero es una aplicación que tiene mucha potencia. Vale la pena dedicarle un rato, para ver las cosas que tiene. La parte de "Leaks" sobre todo es fundamental para encontrar problemas de memoria, que si no, son muy difíciles de detectar.

1 comentario:

  1. ARC evita la mayoría del manejo de memoria a mano, pero no todo.
    La memoria creada por C (malloc) aun debe ser mantenida por el developer.
    Dependiendo con que frameworks se trabaje, muchos (los de mas bajo nivel) aun están en C puro.

    ResponderEliminar