Хранение данных в статических объектах без утечек памяти

Я пытаюсь отследить проблему, когда некоторые пользователи начали получать ошибки памяти в KitKat. Я не видел их в предыдущих версиях, но знаю, что использование памяти иногда намного выше, чем я ожидал.

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

Они есть:

Notification   //as in when a notification is raise
PendingIntents   
BroadcastReceiver //as in the object passed to: context.registerReceiver     
SharedPreferences 

Из того, что я могу сказать, я не думаю, что они содержат объекты контекста, но я не уверен.

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

1 ответ

Решение

Я бы посоветовал вам запустить ваше приложение и использовать все действия, которые содержит ваше приложение, а также несколько раз переключать ориентацию, затем выходить из приложения и запускать GC (есть кнопки для всего этого) после того, как выгрузите hprof (это предполагает, что вы используете Eclipse) и запустите отчет о подозреваемых утечках, используйте кнопку гистограммы для просмотра того, какие распределения были сделаны, и сортируйте #objects (попробуйте отфильтровать по имени вашего пакета, так как String / byte[] и т. Д. Имеют тенденцию доминировать в таком отчете о подозрительных утечках, даже если не должно быть утечек). Руководство по отладке памяти в Android.

Что касается ваших вопросов к этим конкретным классам (когда я говорю, "может утечь контекст", я имею в виду контекст активности, так как приложение одноэлементное):

  • Уведомления предпочтительно обрабатываются Notification.Builder, который использует контекст, так что удерживание уведомления в статической переменной может привести к утечке контекста.

  • PendingIntents получаются из вспомогательных методов, где контекст отправляется в см. PendingIntent также может пропускать контекст

  • BroadcastReceivers может быть зарегистрирован в манифесте (здесь нет утечки контекста) или во время выполнения, если вы не отменили регистрацию в onPause (регистрация в onResume), вы можете утечь BroadcastReceiver, который, в свою очередь, утечки текущего контекста активности (это)

  • SharedPreferences извлекаются из текущей деятельности, если ваша деятельность воссоздается, может также быть утечка

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

Другие вопросы по тегам