¿Por qué se trata de una pérdida de memoria

Me encontré con una biblioteca para la detección de fugas de memoria en Android (Java) llamado LeakCanary, pero no puede entender el ejemplo donde se fugan de la memoria. ¿Podría alguien explicar cómo y por qué el código mostrado en su ejemplo es una pérdida de memoria.

class Cat { } class Box { Cat hiddenCat; } class Docker { static Box container; } // ... Box box = new Box(); Cat schrodingerCat = new Cat(); box.hiddenCat = schrodingerCat; Docker.container = box; 

Y entonces miran la variable schrodingerCat para los escapes que da una fuga demostrada como sigue (que no sé relacionarse al código antedicho).

 * GC ROOT static Docker.container * references Box.hiddenCat * leaks Cat instance 

Cualquier ayuda con la explicación de la fuga y cómo la detección se relaciona con ella sería muy provechosa. También algunos buenos artículos para los principiantes sería agradable.

¡Gracias!

En primer lugar, vamos a entender lo que es un escape de memoria :

Definición

Memory Leak se asigna a los datos (bitmaps, objetos, matrices, etc) en la RAM que el recolector de basura (GC) no puede liberar, aunque ya no es necesario por el programa.

Ejemplo

Un usuario está abriendo una vista que muestra una imagen. Cargamos el mapa de bits a la memoria. Ahora el usuario sale de la vista y la imagen ya no es necesaria y no hay referencia a ella desde el código. En ese momento el GC entra en acción y lo retira de la memoria. PERO , si todavía teníamos una referencia a él, el GC no sabrá que está bien para la eliminación y se habría quedado en la memoria RAM tomando espacio innecesario – aka Memory Leak .

Gato en una caja

Digamos que tenemos un objeto Cat en nuestra aplicación, y lo mantenemos en un objeto Box. Si mantenemos la casilla (tenemos una referencia al objeto Box) y el Box contiene el Cat, el GC no podrá limpiar el objeto Cat de la memoria.

El Docker es una clase que tiene una referencia estática a nuestra caja. Esto significa que a menos que lo anule o reasigne el valor, el Docker seguirá haciendo referencia a la Caja. Prevención de la Caja (y el gato interior) de ser retirado de la memoria por el GC.

Entonces, ¿necesitamos el gato? ¿Sigue siendo relevante para la aplicación?

Esto es hasta el desarrollador para decidir cuánto tiempo necesitamos el gato para. LeakCanary y otras herramientas de diagnóstico sugieren un posible escape de memoria. Ellos piensan que el objeto (Cat) podría no ser necesario más así que alertan que es una fuga.

Resumen

En el ejemplo, dan un escenario común de una pérdida de memoria. Cuando se utiliza una referencia estática, evitamos que el GC limpie un objeto. Usted debe leer esto:

 * GC ROOT static Docker.container * references Box.hiddenCat * leaks Cat instance 

como:

  • Objeto Gato podría no ser utilizado más, pero no fue retirado de la memoria por el GC.
  • La razón por la que el objeto Cat no se eliminó es porque Box tiene una referencia a él.
  • La razón por la que el objeto Box no se ha eliminado es porque el Docker tiene una referencia estática.
  • La referencia estática por Docker es la ROOT del árbol que causa la posible fuga.

Parece que la instancia de RefWatcher utiliza para "ver la variable schrodingerCat para las filtraciones":

 refWatcher.watch(schrodingerCat); 

Fuerza un conjunto de GC pasa y si la referencia pasada no se recoge durante esos GC pasa se considera una fuga.

Puesto que el Docker.container.hiddenCat estático está manteniendo una referencia enraizada GC al objeto originalmente conocido como schrodingerCat , no puede ser GC'ed así que cuando pides RefWatcher para comprobarlo. Por lo tanto, le permite saber que el objeto no se puede recopilar.

Le sugiero que lea esta respuesta https://stackoverflow.com/a/11908685/1065810

Probablemente le ayudará a entender el ejemplo anterior.

En resumen, en su ejemplo, la clase Docker mantiene una referencia a una caja. Incluso cuando ya no se necesita la caja contenedora, la clase Docker todavía tiene una referencia a ella creando así una pérdida de memoria.

Déjeme saber si eso ayuda.

  • Android Studio - Cómo aumentar el tamaño del montón asignado
  • Fuga de memoria MediaControllerCompat
  • ¿Cómo entender que muestra LeakCanary?
  • Jit: Redimensionar JitTable de 512 a 1024 y así sucesivamente ... ¿qué es esto?
  • Detección de fugas de memoria nativas en el código JNI de Android
  • Aplicación de Android con límite de tamaño de memoria
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.