Байт [] получает мусор, в отличие от Bitmap?Или это то же самое? - PullRequest
1 голос
/ 26 января 2012

Я испытываю кучу дурацких (и очень трудно найти) утечек памяти в моем приложении для Android. У меня нет статических растровых изображений (это то, что во всех руководствах, касающихся утечек растровых изображений, не рекомендуется делать). Однако у меня есть растровое изображение, которое я храню в своем классе Application, которое используется кучей моих действий. Я призываю recycle() сообщить об этом, когда завершится последнее действие, но мне интересно, будет ли безопаснее просто хранить данные как byte[] и создавать Bitamp из них локально в каждом действии, которое их использует, и затем отпустите его, как только это будет сделано. Мне любопытно, что byte[] - это конструкция, которая облегчает сборку мусора на виртуальной машине по сравнению с растровым изображением (которое, похоже, полностью отстой).

Вся помощь с благодарностью.

Ответы [ 3 ]

1 голос
/ 26 января 2012

Изменение с Bitmap на byte[] не решит проблему, которая вызвана сохранением ссылки на объект Bitmap. Вместо вызова recycle() вы должны установить ссылку на null при выходе из последнего действия. Это будет делать все, что делает вызов recycle(), плюс позволяет GC собирать сам объект Bitmap. (ГХ не различает Bitmap и byte[], когда речь идет об утилизации. Объект, на который нет ссылок, - это объект, на который нет ссылок ...)

Единственное, что можно предложить (если Bitmap действительно является источником утечки памяти), это использовать WeakReference<Bitmap> в своем классе приложения вместо жесткого указания. Тогда каждое действие может get() фактическое Bitmap (если оно все еще там). Тогда вам не нужно устанавливать его на null; GC будет автоматически собирать Bitmap, когда нет жестких ссылок, оставляя пустую слабую ссылку.

0 голосов
/ 25 июня 2012

Я знаю, что на этот вопрос уже был дан ответ, но только в качестве примечания: при работе с Bitamps это одна из тех вещей, которые Android обрабатывает изначально (то есть с помощью кода C, а не кода Java).Поэтому, даже если вы отпустите все ссылки на него, он все равно будет храниться в памяти на нативной стороне и будет учитываться в вашем приложении.

0 голосов
/ 26 января 2012

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

Снимок, сделанный камерой, может быть довольно большим.Когда вы открываете изображение как растровое изображение, вы загружаете полный массив в память.Рассмотрим Nexus One с 5-мегапиксельной камерой.Пользовательские снимки, сделанные с помощью устройства, могут быть размером 2048x1536.Используя глубину пикселя 24 бит, мы говорим о почти 9 МБ.Это огромный , если принять во внимание ограничение кучи в 16/24 МБ.

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

BitmapFactory.decodeByteArray(...) (и другие фабричные методы) может принимать объект BitmapFactory.Options, где вы можете указать масштабный коэффициент через inSampleSize.Это не влияет на исходные данные, поэтому вы можете сохранить свое полноразмерное изображение и получить сэмпл растрового изображения в памяти.Вы можете комбинировать это, предварительно используя inJustDecodeBounds = true, чтобы прочитать размер изображения, затем рассчитать масштабный коэффициент на основе размера изображения и размера вашего окна просмотра и, наконец, получить масштабированное растровое изображение.

ЭтоВопрос может быть полезен (не выбранный ответ, но два других с высоким баллом): Странно нехватка памяти при загрузке изображения в растровый объект

Редактировать: упс, опубликовано неправильноссылка на вопрос

...