Що таке витоку пам'яті в Android-розробці?
Програма створює об'єкти, вони лежать у пам'яті і не можуть їх очистити після завершення своєї роботи.
Чому це відбувається?
У Java є власні засоби очищення пам'яті від елементів, що не використовуються. Це складання сміття .
Складальник сміття позначає всі об'єкти, які можна видалити, якщо на них немає посилань. Виток пам'яті - це просто втрачене посилання, яке показує, що об'єкт не може бути видалений.
Складність цього бага
у тому, що до певного часу він не видно і не може заважати.
Є хороша цитата Бенджаміна Франкліна: "Маленька текти потопить великий корабель".
Витоку пам'яті займають оперативну пам'ять програми. Об'єм необробленої пам'яті буде зростати, і одного разу ваш додаток може сповільнитися і вилетіти. Це викликає невдоволення користувачів і, швидше за все, додаток буде видалено.
Один із
найнебезпечніших
випадків, коли програма втрачає посилання на
перегляд
. Здавалося б, цей
вигляд
маленький на екрані. Однак варто пам'ятати, що
подання
має посилання на
активність
(фрагмент). А якщо посилання на перегляд не прибрати, то активність (фрагмент) теж жива. Активність (фрагмент) має посилання всі уявлення на екрані.
Як дізнатися, чи є витоку пам'яті?
Ви можете знайти пам'ять Ліки по-різному. Але найпростіше використовувати Profiler Android-студію.
Порядок дій:
- Стартовий проект
- У нижній панелі натисніть "Профілювальник".
- Виберіть «Пам'ять»
- Натиснути "Force Garbage Collection" (тоді потрібно трохи зачекати)
- Натисніть "Дамп купи Java"
- Фільтрувати список за потрібними класами
- Подивитися кількість об'єктів
На малюнку вище показано, що є чотири об'єкти Activity . Це сталося тому, що програміст дозволив програмі втратити посилання на подання. Користувачі люблять повертати екран телефону. За кожної зміни орієнтації діяльність відтворювалася заново, а стара залишалася лежати у глибині пам'яті.
Якщо ви хочете, щоб спосіб вилову витоків пам'яті був більш цікавим, пропоную вам ознайомитися з бібліотекою LeakCanary .
Як уникнути витоків пам'яті ?
Ось кілька порад:
1. Не створюйте статичні посилання на уявлення. Статичні поля мають той же життєвий цикл, що й ваша програма.
** 2. Не передавайте посилання на об'єкти, які живуть довше, ніж об'єкт, який ви передали. повторного створення активності.
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. Докладніше про них можна прочитати тут:
Без витоків пам'яті наведений вище код виглядав би так:
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-розробці та найпростіші способи їх уникнути. Є ще багато складних ситуацій. Деякі з них будуть розглянуті у таких статтях. Підпишіться нові статті.