470 likes | 652 Views
“Detección de Memory Leaks utilizando Eclipse Memory Analyser ”. Algeciras, jueves 26 de septiembre de 2013. ¿Quien soy?. Rafael David Piernagorda. Co- Founder & Product Manager en. i. Socio en nicia tivas 3D. @ Gatreyu. ¿Qué es un Memory Leak ?.
E N D
“Detección de MemoryLeaks utilizando Eclipse MemoryAnalyser” Algeciras, jueves 26 de septiembre de 2013
¿Quien soy? Rafael David Piernagorda Co-Founder & Product Manager en i Socio en niciativas3D @Gatreyu
¿Qué es un MemoryLeak? MemoryLeak [Fuga de Memoria] es un error software, que hace que no se libere memoria previamente reservada. Muy común en C/C++ . Java implementa GarbageCollector para solucionarlo.
¿Qué es un MemoryLeak? Aún así se producen MemoryLeaks con el GarbageCollector. Pero… ¿Cómo funciona el GarbageCollector? Lo vemos más adelante. Actualmente la memoria de los dispositivos aumenta. ¿Por qué preocuparse?
Memoria en Dispositivos Memoria en los dispositivos va aumentando (Estudio para Smartphones HTC)
Memoria en Dispositivos Entonces ¿Cuál es el problema? Tamaño de pixeles en pantalla aumenta también
Memoria en Dispositivos ¿Y? Supongamos el siguiente caso hipotético: HTC One(2 GB, 1,44 Mpíxeles de pantalla, 1080x1920) Cliente desea una galería con cuadros que al hacer doble click se muestre en pantalla completa a máxima resolución. Fotografías de 1080x1920 con 24 bits de profundidad. Hay 1500 cuadros para visualizar.
Memoria en Dispositivos Consumo de memoria (solo por la lectura de la imagen): 4,32 Mbytes. ¿Y qué? Tenemos 2Gbytes de memoria Ram. Si queda como fuga de memoria (no libera las imágenes), y visualiza solamente 20 cuadros, habrá consumido 86,4 MB. De esta forma solamente podrá visualizar 460 Cuadros (sin apagar el móvil y sin utilizar otra aplicación).
Memoria en Dispositivos Si utiliza visualiza 461 cuadros: Nuestra querida excepción: OutOfMemoryException.
Memoria en Dispositivos • Todo esto en el caso hipotético ya que: • No hemos tenido en cuenta otras aplicaciones, ni la memoria ya consumida. • Se ha considerado que nunca se apagará el dispositivo. • No hemos tenido en cuenta el Heap (en los dispositivos con Honeycomb (Android 4.0) habría saltado antes el OutOfMemoryException) • Hemos utilizado un dispositivo con mucha memoria.
¿Qué es GarbageCollector? Proceso de gestión de memoria, utilizado para liberar aquellas zonas de memoria reservadas que no están siendo utilizadas. Java, lenguaje O/O, hay referencias entre clases.
¿Qué es GarbageCollector? Referencia entre clases: PublicclassTestingClass { privateOtherClass _otherClass; } Aquí TestingClass tiene una referencia a OtherClass, por lo que si TestingClass no se libera de memoria, quedarán ambas referencias: TestingClass y OtherClass.
¿Cómo funciona el GarbageCollector? Lo mejor verlo con un ejemplo. Las referencias entre objetos crean un grafo, que el GarbageCollector recorre para detectar aquellos nodos que ya no están en memoria (han sido liberados). El Garbagecollector siempre comenzará por el nodo GCRoot. La raiz del GC hace referencia a A. La clase A hace referencia a B, y a la clase C. La clase C hace referencia a la clase D Y la clase D hace referencia a E y F
¿Cómo funciona el GarbageCollector? Imaginemos nodo F deja de estar referenciado por D. Cuando el GarbageCollector recorra este árbol, el nodo F no es alcanzado desde el nodo GCRoot por lo tanto será liberado. La clase A hace referencia a B, y a la clase C La clase C hace referencia a la clase D Y la clase D hace referencia a E y F
¿Cómo funciona el GarbageCollector? Supongamos ahora que el objeto con la clase A crea un objeto con la clase G, y que le pasa el objeto de clase C a G, y después se intenta liberar A y forzamos al GC a hacer Collect() ¿Qué creéis que pasará? El objeto A no podrá ser liberada, porque tiene una referencia a C, por lo que mientras dure la vida de G, el Objeto A seguirá activo. Acabamos de tener un MemoryLeak.
HEAP El grafo con las relaciones de los objetos están almacenados en un HEAP. Todas las aplicaciones tienen asociado un Heap. GarbageCollector gestiona el uso de este Heap, siendo este de un tamaño limitado según dispositivo.
HEAP • Tamaños de Heap: • HTC Dream (Google Phone) 16 MB • Droid 24 MB • NexusOne 32 MB • Xoom 48 MB
HEAP • Conceptos asociados al HEAP • DominatorTree => Es aquel árbol cuyos caminos de sus nodos conducen directamente hacia el nodo principal.
HEAP • Conceptos asociados al HEAP • DominatorTree. Este árbol (comienzo con el nodo A) no es dominatortree debido a que el nodo C puede ser alcanzado tanto por el nodo A como el nodo G.
HEAP • Conceptos asociados al HEAP • DominatorTree. Visión en MAT
HEAP • Conceptos asociados al HEAP • ShallowHeap: Nos indica la memoria consumida por un único objeto. • RetainedHeap: Nos indica la memoria consumida por todo el árbol desde ese nodo.
HEAP Conceptos asociados al HEAP
HEAP • ¿Qué ocurre cuando el Heap se llena? • Out Of MemoryException • ¿Por qué no agrandar el heap? • GarbageCollector recorre el heap para liberar la memoria, si es grande, el proceso es lento, y las aplicaciones se vuelven ineficientes.
HEAP • Problema con las imágenes: • Antes de HoneyComb • Heap solo tiene la referencia, la imagen se carga en memoria Nativa. • Es difícil de depurar
HEAP • Problema con las imágenes: • Con HoneyComb (Android 4.0) • Memoria Externa se aloja en el Heap. • Luego, las imagen se cargan en el Heap. • Fácil de depurar.
HEAP • Supongamos, nuestra aplicación anterior. • NexusOne. • Heap: 32 MB • Mpixeles: 0,38 • Fotografías de 24 bits, ocupan: 1,12 MB • Si no se libera la memoria, solo podríamos cargar (en el caso hipotético) 28 cuadros.
¿Qué hacemos si detectamos un MemoryLeak? • 1. Llorar No soluciona nada, pero si te gusta desahogarte así, adelante.
¿Qué hacemos si detectamos un MemoryLeak? • 2. Usar la técnica del Avestruz No soluciona nada. Pero por desgracia es una técnica muy popular entre muchos desarrolladores y Product Manager. Que halla mucha memoria no significa que no pueda pasar. Si quieres que ocurra presenta el producto a un Cliente o Inversor, y el fallo ocurrirá con su mayor consecuencia.
¿Qué hacemos si detectamos un MemoryLeak? • 3. Hacer un análisis del código Investigar la fuga de memoria que existe dentro del código. Utilizar herramientas necesarias para ver las referencias entre los objetos y encontrar las fugas de memoria. Herramienta: Eclipse MemoryAnalyser.
¿Que señales nos indicarían que hay un ML? • Utilizando el Log de Eclipse • Los mensajes del GC tiene esta forma • D/dalvikvm( 29003): GC_CONCURRENT freed 378K, 41% free 3373K/6151K, external 0K/0K, paused 12ms+11ms • Diferentes tipos de mensaje: • GC_Concurrent: Se activa cuando la pila crece, y se quiere recuperar memoria en tiempo de ejecución. • GC_Explicit: Cuando la aplicación fuerza llamar al System.gc() • GC_External_malloc: Se usa para memoria externa. • GC_For_malloc: Se activa cuando el heap se llena y la aplicación necesita más memoria. • GC_HPROF_Dum_Heap: Cuando se crea el HPROF.
¿Que señales nos indicarían que hay un ML? • Utilizando el Log de Eclipse • Análisis del Log • D/dalvikvm( 29003): GC_CONCURRENT freed 378K, 41% free 3373K/6151K, external 0K/0K, paused 12ms+11ms • “freed 378k” nos indica la memoria liberada. • “41% free 3373k/6151k” nos indica el % de memoria libre. • “external 0K/0K” nos indica la cantidad de memoria externa liberada.
¿Que señales nos indicarían que hay un ML? • Utilizando el Log de Eclipse • Para detectarlo, en primer lugar creamos un filtro en LogCat
¿Que señales nos indicarían que hay un ML? • Utilizando el Log de Eclipse • Dejar ejecutar la aplicación, y una vez que tengamos los suficientes mensaje, echar un vistazo.
¿Que señales nos indicarían que hay un ML? • 2. Utilizando el DDMS (DalvikDebug Monitor Server) • Es más visual y fácil de entender
¿Que señales nos indicarían que hay un ML? • 2. Utilizando el DDMS (DalvikDebug Monitor Server) • La memoria usada aumenta, al igual que los objetos.
¿Que señales nos indicarían que hay un ML? • 3. Utilizando el MAT Report • Podemos ver el overview del HeapDump
¿Que señales nos indicarían que hay un ML? • 3. Utilizando el MAT Report • Utilizamos el Top Consumer
¿Que señales nos indicarían que hay un ML? • 3. Utilizando el MAT Report • Utilizamos el Top Consumer
Detección de MemoryLeak en Vivo • MAT se descarga desde: http://eclipse.org/mat/ • O usando Update Manager de Eclipse: http://www.eclipse.org/mat/downloads.php • Primera demostración
Detección de MemoryLeak en Vivo • ¿Qué está pasando?
Detección de MemoryLeak en Vivo • ¿Qué está pasando? • Cuando se da la vuelta al dispositivo, se crea un nuevo • MainActivity, y se libera el anterior. Pero este nunca es • liberado. • La clase MainActivity hace referencia a ConsumingClass • que a su vez hace referencia a MainActivity, y el objeto • ConsumingClass es insertado en un Stack y nunca se libera.
Detección de MemoryLeak en Vivo • ¿Qué está pasando?
Detección de MemoryLeak en Vivo • Pero, ¿y si necesitamos pasar el contexto a la clase • ConsumingClass, como lo hacemos? • Si queremos pasar el contexto, para acceder por ejemplo a • los recursos, no tenemos que pasar toda la actividad, • solamente utilizar getApplicationContext().
Detección de MemoryLeak en Vivo • ¿Qué está pasando?
Detección de MemoryLeak en Vivo • Segundo ejemplo, clásico ejemplo de MemoryLeak. • Creamos una innerclass (LeakClass) dentro de una • actividad (MainClass) pero no la denotamos como estática, • y creamos un variable estática que sea de la clase • LeakClass. • ¿Qué ocurre?
Detección de MemoryLeak en Vivo • Se ha creado un Leak de un MainActivity, debido a que la • innerclass (LeakClass) está encapsulada a la MainActivity • que es la Outer.