Размер растрового изображения превышает бюджет виртуальной машины, не понимая, почему - PullRequest
4 голосов
/ 14 июня 2011

Я просмотрел проблемы «Размер растрового изображения превышает бюджет виртуальной машины», но ни одно из решений не представляется мне подходящим. Я не понимаю, почему моя программа иногда выдает эту ошибку, потому что то, как я ее использую, похоже, не вызывает никаких утечек памяти. Мои следы стека указывают на метод BitmapFactory.decodeResource (). У меня есть фоновое изображение, которое я использую для рисования на холсте, и вот как я его инициализирую:

Bitmap backgroundImage = BitmapFactory.decodeResource(getResources(),
    R.drawable.background);
backgroundImage = resizeImage(backgroundImage, w, h);

Вот как я это использовал:

canvas.drawBitmap(backgroundImage, 0, 0, paint);

Я думал, что использование backgroundImage = null в методе onDestroy поможет, но это ничего не дало. В моей программе нет другой ссылки на ресурс фонового изображения, кроме файла XML, но я не думаю, что это влияет на него. Может ли кто-нибудь объяснить мне, почему это происходит и как это исправить?

Кстати, в этом приложении нет изменений ориентации экрана.

1 Ответ

3 голосов
/ 14 июня 2011

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

Прежде чем установить его в ноль, просто вызовите Bitmap # recycle () в Bitmap:

protected void onDestroy() {
    if (this.backgroundImage != null) {
        this.backgroundImage.recycle();
        this.backgroundImage = null;
    }
}

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

Общий метод заключается в использовании версии с тремя аргументами BitmapFactory.decodeResource (), с BitmapFactory.Options # inJustDecodeBounds для первого прохода, чтобы получить ширина / высота растрового изображения (хотя в вашем случае, поскольку оно исходит из ресурсов приложения, нет причин, по которым вам даже придется это делать ... но я все равно объясню); затем определите правильный размер выборки на основе целевого размера и декодируйте растровое изображение во второй раз. Это обычно приводит к гораздо меньшему использованию памяти, особенно для очень больших изображений (например, с inSampleSize, установленным в 2, он декодирует полноразмерное растровое изображение, но выделяет достаточно памяти только для растрового изображения, равного половине исходного размера, уменьшая масштаб растрового изображения в процессе).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...