Рина Сергеева
Рина Сергеева27 декабря 2018 г. 1:53

Немного об утечках памяти и способах их избежать

Что такое утечки памяти в Android-разработке?

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

Почему это происходит?

В Java есть собственные средства очистки памяти от неиспользуемых элементов. Это [ сборка мусора ] [id].

Сборщик мусора помечает все объекты, которые можно удалить, если на них нет ссылок. Утечка памяти - это просто потерянная ссылка, которая показывает, что объект не может быть удален.

Сложность этого бага в том, что до определенного времени он не виден и не может мешать.
Есть хорошая цитата Бенджамина Франклина: «Маленькая течь потопит большой корабль».
Утечки памяти занимают оперативную память приложения. Объем необработанной памяти будет расти, и однажды ваше приложение может замедлиться и вылететь . Это вызовет недовольство пользователей и, скорее всего, приложение будет удалено...


Один из самых опасных случаев, когда программа теряет ссылку на просмотр . Казалось бы, этот вид маленький на экране. Однако стоит помнить, что представление имеет ссылку на активность (фрагмент). А если ссылку на просмотр не убрать, то Активность (Фрагмент) тоже живая. Активность (фрагмент) имеет ссылки на все представления на экране.

Как узнать, есть ли утечки памяти?

Вы можете найти память Лики по-разному. Но проще всего использовать Profiler Android-студию.

Порядок действий:

  • Стартовый проект
  • В нижней панели нажмите «Профилировщик».
  • Выберите «Память»
  • Нажать "Force Garbage Collection" (тогда нужно немного подождать)
  • Нажмите "Дамп кучи Java"
  • Фильтровать список по нужным классам
  • Посмотреть количество объектов

На рисунке выше показано, что существует четыре объекта Activity . Это произошло потому, что программист позволил программе потерять ссылки на представление . А пользователи любят поворачивать экран телефона. При каждой смене ориентации деятельность воссоздавалась заново, а старая оставалась лежать в глубине памяти.

Если вы хотите, чтобы способ отлова утечек памяти был более интересным, то предлагаю вам ознакомиться с библиотекой LeakCanary .

Как избежать утечек памяти ?

Вот несколько советов:

1. Не создавайте статические ссылки на представления. Статические поля имеют тот же жизненный цикл, что и ваше приложение.

2. Не передавайте ссылки на объекты, которые живут дольше, чем объект, который вы передали. Например: не передавайте классу ссылки Runnable на View , так как новый поток будет продолжать live даже после повторного создания активности.

public class LeakingRunnable implements Runnable {

    private View view;

    LeakingRunnable(View view){       //don't do that!
        this.view = view;
    }
    @Override
    public void run() {
        // do some work
    }
}

И как перенести view в Runnable ?

Используйте другие типы ссылок.
В Java, помимо обычных "жестких ссылок" , есть и другие "мягкие ссылки" и "слабые" . Правильно их называть:

  • WeakReference
  • SoftReference
  • Phantom Reference

Наличие «мягких ссылок» больше не будет мешать сборщику мусора удалять Activity. Подробнее о них можно прочитать здесь: differences between weak, soft, phantom and normal links in Java

Без утечек памяти приведенный выше код выглядел бы так:

public class NoLeakingRunnable implements Runnable {

    @NonNull
    private final WeakReference<View> viewRef;

    public NoLeakingRunnable(@NonNull View view){
        this.viewRef = new WeakReference<>(view);         //do that!
    }
    @Override
    public void run() {
        View view = viewRef.get();
        // do some work
    }
}  

3. Необходимо сделать внутренние классы статическими Activity.

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

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

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
MB

Qt - Тест 001. Сигналы и слоты

  • Результат:57баллов,
  • Очки рейтинга-2
MB

C++ - Тест 001. Первая программа и типы данных

  • Результат:60баллов,
  • Очки рейтинга-1
GK

C++ - Тест 005. Структуры и Классы

  • Результат:0баллов,
  • Очки рейтинга-10
Последние комментарии
J
JonnyJo8 июня 2023 г. 12:14
Qt/C++ - Урок 019. Рисуем треугольник в Qt5. Позиционирование в QGraphicsScene Евгений, здравствуйте! Решил поэкспериментировать немного с кодом из этого урока, нарисовать вместо треугольника квадрат и разобраться с координатами. В итоге, запутался. И ни документация,…
Evgenii Legotckoi
Evgenii Legotckoi25 мая 2023 г. 4:49
Как написать игру на Qt - Урок 2. Анимация героя игры (2D) Код на строчка 184-198 вызывает перерисовку области на каждый 4-й такт счётчика. По той логике не нужно перерисовывать объект постоянно, достаточно реже, чем выполняется игровой слот. А слот вып…
J
JonnyJo21 мая 2023 г. 10:49
Как написать игру на Qt - Урок 2. Анимация героя игры (2D) Евгений, благодарю! Всё равно не совсем понимаю :( Если муха двигает ножками только при нажатии клавиш перемещение, то что, собственно, делает код со строк 184-198 в triangle.cpp? В этих строчка…
Evgenii Legotckoi
Evgenii Legotckoi21 мая 2023 г. 5:57
Как написать игру на Qt - Урок 2. Анимация героя игры (2D) Добрый день. slotGameTimer срабатывает по таймеру и при каждой сработке countForSteps увеличивается на 1, это не зависит от нажатия клавиш, нажатая клавиша лишь определяет положение ножек, котор…
Сейчас обсуждают на форуме
T
Twanger7 июня 2023 г. 11:12
Ошибка при выполнении триггерной функции (GreenPlum) Есть 3 таблицы fact_amount со структурой: CREATE TABLE fact_amount ( id serial4 NOT NULL, fdate date NULL, type_activity_id int4 NULL, status_id int4 NULL, CONSTRAINT fact…
AR
Alexander Ryabikov6 июня 2023 г. 13:35
Работа с QFileSystemModel Вопросик по теме QFileSystemModel в Linux. Он, как и положено, обновляется самостоятельно, если директория локальная. Но, вот, сетевая папка (у меня шара samba) не обновляется. Как её можно…
Evgenii Legotckoi
Evgenii Legotckoi16 апреля 2023 г. 4:07
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Да, это возможно. Но подобные вещи лучше запускать через celery. То есть drf принимает команду, и после этого регистрирует задачу в celery, котроый уже асинхронно всё это выполняет. В противном …
АБ
Алексей Бобров14 декабря 2021 г. 19:03
Sorting the added QML elements in the ListModel I am writing an alarm clock in QML, I am required to sort the alarms in ascending order (depending on the date or time (if there are several alarms on the same day). I've done the sorting …

Следите за нами в социальных сетях