Что на самом деле делает Bitmap # recycle () в Android Honeycomb? - PullRequest
15 голосов
/ 21 октября 2011

Я пишу очень ресурсоемкое приложение для Android Honeycomb, и я очень внимательно следил за recycle() неиспользованными Bitmap с, где это возможно;действительно, это необходимо для того, чтобы приложение вообще работало, поскольку Bitmap s постоянно циклически включается и выключается из памяти.Однако я только что реализовал onConfigurationChanged() в Activity, и поэтому (по ряду причин) я пытаюсь поместить процедуры освобождения памяти в onStop().

В настоящее время мой метод onStop():

  • устанавливает некоторые View с для отображения по умолчанию Drawable;
  • вызовов recycle() на Bitmap с, ранее использовавшихся этими View с;
  • пустые ссылки на Bitmap s.

К сожалению, при использовании профилировщика памяти Eclipse кажется, что не влияет на использование памяти вообще .

Как вы можете себе представить, приложив столько усилий, чтобы высвободить ресурсы на номинально собранном языке, я бы надеялся на еще больший эффект.Итак, мой вопрос: что делает recycle()?Это фактически вызывает сборку мусора, или система будет удерживать память - даже если вы звоните System.gc() - до тех пор, пока не почувствуете необходимость от чего-то избавиться?

NB Я знаю Bitmap s arenфактически не удерживался в обычной куче, но я думал, что вызова recycle() было достаточно, чтобы убедиться, что они выпали из родной кучи.

ЧАСТЬ ОТВЕТА

Я обнаружил, что если ImageView содержит Bitmap, который был переработан, данные Bitmap все еще сохраняются в памяти до тех пор, пока на ImageView не будет вызван setImageBitmap(null).Это может даже иметь место, если вызываются setImageResource(...) или setImageDrawable(...) (они загружались в сравнительно небольшой пакет из девяти патчей - однако анализ MAT показывает, что это не удаляет большой Bitmap, который содержался в приватномчлены ImageView).Простой вызов этой функции на onStop() выкинул около 10 МБ из кучи нашего приложения.По-видимому, это может быть не так для сборок Android до Honeycomb.

Ответы [ 3 ]

6 голосов
/ 21 октября 2011

Как говорит Джастин, растровые данные не выделяются в куче виртуальных машин.Существует ссылка на него в куче виртуальной машины (которая мала), но фактические данные выделяются в собственной куче базовой графической библиотекой Skia.[Обратите внимание, что это могло измениться на более поздних уровнях Android, но верно для 2.1 и 2.2] Когда вы выполняете recycle (), который отмечает как небольшую часть в куче виртуальной машины, так и фактические данные в собственной куче, как свободные и доступные дляGC.Но фактическая коллекция выполняется двумя различными механизмами GC.Часть в куче виртуальных машин собирается GC Davlik - и вы можете видеть, что это происходит через DDMS.Но данные собственной кучи собираются Gia Skia, которая выглядит более ленивой (она работает реже?).Это означает, что даже при строгих функциях recycle () можно опередить GC с собственной кучей.К счастью, есть механизмы для мониторинга состояния родной кучи.Смотрите BitmapFactory OOM сводит меня с ума .

6 голосов
/ 24 октября 2011

Я обнаружил, что в Honeycomb и далее, если ImageView содержит Bitmap, который был переработан, данные Bitmap все еще сохраняются в памяти до тех пор, пока setImageBitmap(null) не будет вызван в ImageView.Это может даже иметь место, если вызываются setImageResource(...) или setImageDrawable(...) (в этом случае очень большое растровое изображение было заменено на довольно маленькое исправление с девятью патчами, но только когда setImageBitmap(null) вызывалось до загрузкипамять фактически распорядилась).

3 голосов
/ 21 октября 2011

Recycle освобождает собственную память, выделенную для растрового изображения. Фактический объект Bitmap останется в куче Dalvik до следующей сборки мусора (но память, занятая этим объектом, незначительна).

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

...