que - ¿Cómo saber si una aplicación de Android está perdiendo memoria?
porque mi celular dice memoria llena si no tengo nada (5)
Al desarrollar una aplicación, noté que eventualmente se bloqueó porque la JVM no podía asignar más memoria. Usando el comando meminfo adb shell dumpsys, pude ver que el montón nativo asignado creció mientras cambiaba de actividades hasta que se acercó a 16M, cuando se estrelló. Creo que ahora he corregido el código para evitar que esto suceda, pero me doy cuenta de que las cifras devueltas por ..meminfo varían un poco y, en general, parecen aumentar ligeramente ahora.
Básicamente, no estoy seguro de si deberían volver a los mismos valores cuando inicio y detengo una aplicación. Tengo estas cifras y no estoy seguro de si significan que tengo una pérdida de memoria o no:
En la pantalla de inicio, la aplicación en la memoria (PID se ve en DDMS), pero no se ejecuta
adb shell dumpsys meminfo (PID relevante) da:
native dalvik other total
size: 5248 4039 N/A 9287
allocated: 5227 3297 N/A 8524
free: 12 742 N/A 754
(Pss): 2183 3534 1726 7443
(shared dirty): 1976 4640 876 7492
(priv dirty): 2040 1664 940 4644
La aplicación comenzó desde la pantalla de inicio, las actividades iniciadas fueron:
pantalla de inicio -> modo de selección -> Actividad 1, luego todo retrocedido usando el botón Atrás, hasta que vuelva a la pantalla de inicio
meminfo ahora:
native dalvik other total
size: 5572 4231 N/A 9803
allocated: 5497 3153 N/A 8650
free: 74 1078 N/A 1152
(Pss): 2479 3614 1742 7835
(shared dirty): 1976 4632 876 7484
(priv dirty): 2336 1740 956 5032
proceso repetido:
native dalvik other total
size: 5696 4231 N/A 9927
allocated: 5211 2949 N/A 8160
free: 392 1282 N/A 1674
(Pss): 2515 3713 1742 7970
(shared dirty): 1976 4632 876 7484
(priv dirty): 2372 1840 956 5168
La herramienta de análisis de memoria Eclipse (que no encuentro tan informativa) informa sobre los siguientes "sospechosos de fugas":
3,143 instances of "java.lang.Class", loaded by "<system class loader>" occupy 736,760 (35.69%) bytes.
Biggest instances:
class com.ibm.icu4jni.util.Resources$DefaultTimeZones @ 0x40158fe0 - 165,488 (8.02%) bytes.
class android.text.Html$HtmlParser @ 0x400eebd8 - 126,592 (6.13%) bytes.
class com.google.googlenav.proto.GmmMessageTypes @ 0x43d183d8 - 56,944 (2.76%) bytes.
class org.apache.harmony.security.fortress.Services @ 0x40071430 - 51,456 (2.49%) bytes.
class android.content.res.Resources @ 0x4004df38 - 33,584 (1.63%) bytes.
class android.text.AutoText @ 0x400f23c8 - 31,344 (1.52%) bytes.
Keywords
java.lang.Class
Details »
Problem Suspect 2
8,067 instances of "java.lang.String", loaded by "<system class loader>" occupy 497,304 (24.09%) bytes.
Keywords
java.lang.String
Details »
Problem Suspect 3
54 instances of "org.bouncycastle.jce.provider.X509CertificateObject", loaded by "<system class loader>" occupy 256,024 (12.40%) bytes. These instances are referenced from one instance of "java.util.HashMap$HashMapEntry[]", loaded by "<system class loader>"
Keywords
org.bouncycastle.jce.provider.X509CertificateObject
java.util.HashMap$HashMapEntry[]
Todos los comentarios serán recibidos con gratitud.
El registro y el desregistro del receptor provocarán pérdidas de memoria
Como, por ejemplo, si ha registrado el receptor con registerReceiver () y en la aplicación, intenta registrarlo nuevamente sin cancelar el registro, lo que provocará problemas de pérdida de memoria.
Tengo que saber esto de la depuración y la corrección de errores.
En MAT, casi nunca me he encontrado con un "sospechoso de fugas" que en realidad fue una fuga. Lo que realmente está buscando son objetos que se retienen después de un barrido de GC que no debería ser.
Por ejemplo, supongamos que tengo una actividad en el Tablero que puede iniciar las Actividades A y B. Yo lanzo el Tablero, luego inicio la actividad A, presiono el botón Atrás, inicie la actividad B y presioné el botón Atrás.
Usando la vista de depuración de Eclipse, puede forzar un evento de recopilación de GC a través del botón "Causa GC". Ahora, haga clic en el botón "Volcar archivo HPROF" e inicie MAT. Haga clic en el enlace "Árbol de dominador".
En este punto, esperaría que cualquier memoria asociada con las actividades A y B se haya recopilado como basura a menos que haya un error en el código. Normalmente, esto es lo que calificaría como una ''pérdida de memoria'' en la aplicación.
Esto ocurre con mayor frecuencia debido a contextos retenidos, que pueden consumir mucha memoria ya que los contextos a menudo representan componentes grandes (actividades, servicios, etc.).
Cualquier cosa que parezca sospechosa en el Árbol de Dominator puede investigarse más fácilmente a través de la opción "Ruta a las raíces del GC" -> "excluir referencias débiles" (disponible a través del menú del botón derecho). La vista de las raíces de path2gc es probablemente la forma más fácil de encontrar qué objetos contienen referencias a objetos de tal manera que no puedan liberarse.
Una vez que encuentre que se retienen referencias inesperadas, puede demorar más en investigar el código para comprender por qué. Si tiene que ver con un componente del sistema / sistema operativo, grepcode es tu amigo :)
Mientras se comprueba el resultado de la herramienta Analizador de memoria, la herramienta Mat no promete encontrar una memory leak
pero muestra un problem
o un suspect
según su script
La herramienta MAT hace que la vista PIE Chart, Dominator Tree, Path 2 GC se base en el análisis del montón de aplicaciones en ejecución
El desarrollador puede analizar el uso de la memoria en función del resultado anterior y mejorar su programación de aplicaciones
Muy buen enlace para saber más acerca de cómo eliminar la pérdida de memoria es: here
También: video de Google IO 2011 que explica la herramienta MAT , Document , Blog1 y Blog2
Según mi experiencia con la creación de aplicaciones de Android, el sistema operativo parece dejar mucha basura en la memoria. Sin embargo, cuando el dispositivo lo necesita para algo importante, tomará (casi indiscriminadamente) lo que necesite. Incluso si sobrescribe un dato en otra aplicación actualmente abierta.
Aparte de eso, es probable que haya otras cosas en el fondo que afecten sus números, por lo que no creo que podamos extraer información concluyente de ellos. Si una aplicación que creó tiene una fuga, entonces es muy probable que esté haciendo algo que podría causar una pérdida de memoria en cualquier otro entorno basado en Java. Un artículo como: http://www.ibm.com/developerworks/library/j-leaks/ debería ayudar a solucionar la mayoría de los problemas de fugas.
Si tengo problemas de memoria con mi aplicación, estoy usando la versión estándar de la herramienta ddbms incluida en las herramientas de desarrollo de Android.
Eche un vistazo a este enlace: http://android-developers.blogspot.com/2009/02/track-memory-allocations.html
Con esta herramienta puede ver el consumo de memoria desde "el punto de vista de Java" para ver qué objetos están bloqueando la mayor parte de su memoria. Esto le dará la posibilidad de localizar con precisión la pérdida de memoria que está experimentando y optimizando su código.
La salida que ha proporcionado proporciona solo una descripción general de toda la memoria utilizada en su aplicación, pero no cómo se utiliza.