Нужно ли вызывать Bitmap.recycle() после использования (в Android)?

Согласно справочному документу Android Bitmap.recycle():

Освободите собственный объект, связанный с этим растровым изображением, и очистите ссылки на данные пикселя. Это не освободит пиксельные данные синхронно; он просто позволяет собирать мусор, если нет других ссылок. Растровое изображение отмечено как "мертвое", что означает выдает исключение, если вызывается getPixels() или setPixels(), и ничего не рисует. Эта операция не может быть отменена, поэтому она должна вызывается только в том случае, если вы уверены, что для битовая карта. Это расширенный вызов и обычно не нужно вызывать, так как нормальный процесс GC освободит эту память, когда нет больше ссылок на это растровое изображение.

Но многие книги, которые я читаю, предлагают освободить память, вызывая Bitmap.recycle(), как только убедитесь, что она больше не нужна.

Из-за этого я запутался: нужно ли вызывать Bitmap.recycle() после использования?

Ответ 1

Это зависит.

Если вы запускаете свое приложение на Android 3.0 и выше, оно не нужно, поскольку GC позаботится об этом отлично.

Однако, если вы запускаете ваше приложение на более старых версиях, так как GC плохо отслеживает растровые изображения (он считает, что они имеют размер ссылки), вы можете получить OOM, как показано на лекции по Google IO здесь.

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

На самом деле, я помню, я задавал подобный вопрос здесь.

Также, если вам нужен дополнительный контроль растровых изображений с использованием JNI, ознакомьтесь с этим постом.

Короче говоря, ответ таков: он больше не нужен, но все же рекомендуется.


РЕДАКТИРОВАТЬ: Начиная с Android 8.0, битовые карты хранятся в собственной памяти, поэтому труднее достичь OOM. На самом деле это технически невозможно, так как вместо этого вы столкнетесь с другими проблемами. Более подробную информацию об этом можно найти здесь.

Ответ 2

Это не обязательно, но настоятельно рекомендуется! Это ускорит процесс освобождения памяти и избавит вас от пыток с исключением из памяти.

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

Ответ 3

Раньше Android 3.0 Bitmaps выделяет собственную память для хранения пикселей, а вызовы recycle() удаляют в этой области.

Даже при том, что GC не гарантирует освобождение этой памяти, если для этого есть какие-либо ссылки.

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

Ответ 4

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