В Android‑приложении наблюдается утечка памяти при хранении Context в статическом поле, пример: public class MyActivity extends Activity { private static Drawable bg; protected void onCreate(...) { bg = getResources().getDrawable(R.drawable.bg); } } — в чём проблема, как исправить и какими инструментами искать подобные утечки

12 Ноя в 10:17
3 +3
0
Ответы
1
Проблема
- Статическое поле является GC-root: если в него положить Drawable, который ссылается на Context/Activity (через Resources, Theme, callback и т.д.), Activity не будет освобождена — утечка памяти.
- В вашем примере `bg` удерживает ресурс, связанный с Activity, и Activity не может быть собрана сборщиком мусора.
Как исправить (кратко и по делу)
- Не храните Context, View или Drawable, полученные из Activity, в static-полях.
- Если нужен глобальный Context, используйте application context: `getApplicationContext()` или храните `Application` (но помните про тему — application context не содержит Activity theme).
Пример безопасной загрузки:
```
Drawable bg = ContextCompat.getDrawable(getApplicationContext(), R.drawable.bg);
```
- Для кэша используйте LruCache или WeakReference вместо сильной статической ссылки:
```
private static WeakReference bgRef;
Drawable bg = bgRef != null ? bgRef.get() : null;
if (bg == null) {
bg = ContextCompat.getDrawable(getApplicationContext(), R.drawable.bg);
bgRef = new WeakReference(bg);
}
```
- Лучше хранить лишь идентификатор ресурса (например `int resId`) в статике и загружать Drawable при необходимости.
- Для больших Bitmap используйте LruCache и освобождайте/рецайклируйте при необходимости (для старых API).
- Не пытайтесь «обнулять» статические поля в onDestroy как основное решение — лучше не держать их вообще.
Инструменты для поиска утечек
- LeakCanary — автоматическое обнаружение утечек в приложении, простая интеграция.
- Android Studio Memory Profiler — запись heap dump, отслеживание объектов, view roots, allocation tracking.
- Захват heap dump + анализ в MAT (Eclipse Memory Analyzer) — просмотр путей от GC roots до утечек (реализует подсказки «leak suspects»).
- adb/bugreport и `hprof-conv` для конвертации дампов, если нужно анализировать вне IDE.
- StrictMode (частично) и Allocation Tracker для локализации подозрительных аллокаций (не прямой детектор утечек, но полезен).
Короткое резюме
- Не храните Context/Activity/Views/Drawable из Activity в static. Используйте application context, слабые ссылки, LruCache или просто храните resId и подгружайте ресурс по необходимости. Для поиска — LeakCanary, Memory Profiler и MAT.
12 Ноя в 10:26
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир