Как найти корень утечек памяти? - PullRequest
4 голосов
/ 18 мая 2011

Мое приложение в основном и редактор изображений. Есть страница приветствия, которая открывает главное действие с намерением. Если во время основной деятельности ориентация меняется, потребление памяти просто удваивается и остается таким же. Если я закрою основное действие, вернитесь к приветствию и снова запустите основное действие. Та же проблема не возникает. Я думаю, что все это указывает на утечку памяти, я исследовал себя, но не мог найти, почему приложение утечки памяти. Я использую контексты приложения, и в моем приложении нет статического поля. Я пытался сбросить кучу и проанализировать ее с помощью MAT, однако я не смог найти ничего хорошего. Я надеялся, что кто-то может показать мне правильное направление, чтобы найти корни утечки памяти или другого возможного объяснения проблемы.

Ответы [ 5 ]

3 голосов
/ 18 мая 2011

Этот конкретный сценарий освещался в презентации Google I | O 2011 . Я рекомендую посмотреть презентацию, так как она поможет вам лучше найти проблему с помощью MAT.

2 голосов
/ 18 мая 2011

В моем приложении произошла серьезная утечка, и хотя я нашел инструмент MAT полезным, я обнаружил, что основной причиной было неправильное управление стеком операций. Я думаю, что самый полезный способ проверить это был из командной строки, используя:

оболочка adb dumpsys meminfo your.package.name

Вы получите вывод типа

adb shell dumpsys meminfo your.package.name
Currently running services:
  meminfo
-------------------------------------------------------------------------------
DUMP OF SERVICE meminfo:
Applications Memory Usage (kB):
Uptime: 150876 Realtime: 150875

** MEMINFO in pid 253 [your.package.name] **
                    native   dalvik    other    total
            size:     5404     4103      N/A     9507
       allocated:     5294     3110      N/A     8404
            free:      101      993      N/A     1094
           (Pss):     2346     3737     2198     8281
  (shared dirty):     1964     4644     1480     8088
    (priv dirty):     2204     1856      956     5016

 Objects
           Views:       30        ViewRoots:        2
     AppContexts:        3       Activities:        2
          Assets:        2    AssetManagers:        2
   Local Binders:       13    Proxy Binders:       16
Death Recipients:        2
 OpenSSL Sockets:        0

 SQL
            heap:        0          dbFiles:        0
       numPagers:        0   inactivePageKB:        0
    activePageKB:        0

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

2 голосов
/ 18 мая 2011

Помните, что в JVM (и даже в JVM типа «я не могу поверить, что он не является JVM») есть много предметов, которые вы используете и которые не совсем под вашим контролем. Таким образом, правильный подход заключается в том, чтобы найти способ убедиться, что в вашем коде нет утечки памяти, и тогда вы узнаете, что, если память цветет, это, скорее всего, какая-то внешняя подсистема или некоторое предполагаемое следствие фактических потребностей приложения в памяти.

Из вашего описания может показаться, что при рендеринге дисплея просто хранится отложенный буфер кэшированной памяти для каждой ориентации экрана.

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

Если вы действительно хотите убедиться, что в конкретной библиотеке хранится кэшированная копия ориентации экрана, вы всегда можете написать небольшую «тестовую» программу, в которой отсутствуют все смешанные факторы (например, остальная часть вашей программы). и посмотрите, как это происходит на экране с изменением ориентации.

Что касается использования VisualVM, он отлично подходит для обнаружения утечек памяти в пользовательском пространстве; однако, поскольку он работает на другой архитектуре и реализации, он может пропустить проблемы с библиотекой, специфичные для платформы.

1 голос
/ 18 мая 2011

VisualVM http://visualvm.java.net/
Он находится в дистрибутиве JDK, начиная с версии 1.6

0 голосов
/ 18 мая 2011

Если ваше приложение является редактором изображений, и вы наблюдаете этот тип поведения, тогда я ожидаю, что вы не перерабатываете битовую память (см. http://developer.android.com/reference/android/graphics/Bitmap.html#recycle%28%29).

Когда ваша ориентация изменится и действие будет разрушено, вам нужно будет найти любые большие растровые изображения, используемые вашими представлениями, а затем либо вызвать recycle для них, либо использовать метод onRetainNonConfigurationInstance (см. http://developer.android.com/reference/android/app/Activity.html#onRetainNonConfigurationInstance%28%29) для передайте его новому экземпляру Activity.

...