Подтвердить что ты не робот

Как определить, действительно ли приложение Android действительно утечки памяти?

При разработке приложения я заметил, что он в конечном итоге потерпел крах, поскольку JVM не могла выделить больше памяти. Используя команду memm shell ddsys adb, я мог видеть, что распределенная нативная куча выросла при переключении активности до тех пор, пока она не приблизилась к 16M, когда она разбилась. Я верю, что теперь я исправил код, чтобы остановить это, но я заметил, что цифры, возвращаемые..meminfo, немного меняются и, как правило, немного повышаются.

В принципе, я не уверен, должны ли они возвращаться к тем же значениям, когда я запускаю и останавливаю приложение. У меня эти цифры, и я не уверен, означают ли они, что у меня утечка памяти или нет:

На главном экране приложение в памяти (PID, замеченное в DDMS), но не работает

adb shell dumpsys meminfo (соответствующий PID) дает:

                    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

Приложение началось с главного экрана, начались действия:

экран заставки → режим выбора → Действие 1, затем все будут отменены с помощью кнопки "Назад", пока на главном экране

meminfo сейчас:

                    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

повторяется процесс:

                    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

Инструмент анализа памяти Eclipse (который я не нахожу всех информационных) отчетов о следующих "подозреваемые в утечке":

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[]

Все комментарии будут с благодарностью получены

4b9b3361

Ответ 1

В MAT я почти никогда не сталкивался с "подозрительным подозреваемым", который был фактически утечкой. То, что вы действительно ищете, - это объекты, которые сохраняются после GC-развертки, которой не должно быть.

Например, предположим, что у меня есть активность Dashboard, которая может запускать действия A и B. Я запускаю Dashboard, затем запускаю активность A, нажимаю кнопку "Назад", запускаю активность B и нажимаю кнопку "Назад".

Используя представление Eclipse Debug, вы можете принудительно выполнить событие сбора GC через кнопку "Причина GC". Теперь нажмите кнопку "Dump HPROF file" и запустите MAT. Нажмите ссылку "Дерево Доминиров".

В этот момент я ожидаю, что любая память, связанная с действиями A и B, будет собрана как мусор, если в коде не было ошибки. Как правило, это то, что я мог бы квалифицировать как "утечку памяти" в приложении.

Это чаще всего происходит из-за сохраняемых контекстов, которые могут съесть много памяти, поскольку контексты часто представляют собой большие компоненты (действия, службы и т.д.).

Все, что выглядит подозрительным в Dominator Tree, может быть наиболее легко исследовано с помощью опции "Путь к GC Roots" → "исключить слабые ссылки" (доступно через меню с щелчком правой кнопкой мыши). Представление корней path2gc, вероятно, самый простой способ найти, какие объекты содержат ссылки на объекты, чтобы они не могли быть освобождены.

Как только вы обнаружите, что неожиданные ссылки сохраняются, может потребоваться больше копания через код, чтобы понять, почему. Если это связано с компонентом system/OS, grepcode - ваш друг:)

Ответ 2

Регистрация и отмена регистрации приемника приведет к утечке памяти

Как, например, если вы зарегистрировали ресивер с помощью registerReceiver(), и в приложении вы сами пытаетесь зарегистрировать его, не занимаясь регистрацией, это приведет к проблеме утечки памяти.

узнал об этом от отладки и исправления ошибок.

Ответ 3

Основываясь на моем опыте создания Android-приложений, ОС, похоже, оставляет много мусора в памяти. Однако, когда устройство нуждается в этом для чего-то важного, оно (почти без разбора) будет принимать все, что ему нужно. Даже если он перезаписывает данные в другом открывшемся в настоящее время приложении.

В стороне, вероятно, есть несколько других вещей, происходящих в фоновом режиме, которые влияют на ваши номера, поэтому я не верю, что мы можем извлечь из них какую-либо исчерпывающую информацию. Если приложение, созданное вами, протекает, то, скорее всего, что-то вы делаете, что приведет к утечке памяти в любую другую среду на основе Java. Статья, подобная: http://www.ibm.com/developerworks/library/j-leaks/, должна помочь в устранении большинства протекающих проблем.

Ответ 4

Если у меня возникают проблемы с памятью в моем приложении, я использую автономную версию инструмента ddbms, включенную в инструменты разработки Android.

Посмотрите на эту ссылку: http://android-developers.blogspot.com/2009/02/track-memory-allocations.html

С помощью этого инструмента вы можете посмотреть потребление памяти с "точки зрения java", чтобы вы могли видеть, какие объекты блокируют большую часть вашей памяти. Это даст вам возможность точно определить утечку памяти, которую вы испытываете, и оптимизировать свой код.

Выданный вами вывод дает просто обзор всей используемой памяти в вашем приложении, но не как ее использовать.

Ответ 5

проверяя результат инструмента анализатора памяти, инструмент макета не обещает найти memory leak, но показывает problem или suspect на основе script

Инструмент MAT делает диаграмму PIE, дерево Dominator, представление пути 2 GC, основанное на запуске анализа кучи приложений

Разработчик может анализировать использование памяти на основе приведенного выше результата и улучшать их прикладное программирование

Очень хорошая ссылка, чтобы узнать больше о том, как удалить утечку памяти: здесь

Также: Google IO 2011 видео, объясняющее инструмент MAT , Документ, Блог1 и Блог2