2017-02-14 2 views
0

В последней строке я получаю аварии:Недостаточно памяти с LruCache?

InputStream in = new BufferedInputStream(new FileInputStream(file)); 
byte[] buf = new byte[(int) file.length()]; 
int numRead = in.read(buf); 
final Bitmap bitmap = BitmapFactory.decodeByteArray(buf, 0, numRead); <--- crash 

Как избежать этого?

E/dalvikvm-heap: Out of memory on a 31961104-byte allocation. 

Я понимаю, что 31MB - это предел для использования памяти? Использование LRUCache для хранения изображений. Я установил 60 МБ для хранения данных. Это слишком много?

public static int cacheSize = 60 * 1024 * 1024; // 4MiB 
    public static LruCache<String, Bitmap> images = new LruCache<String, Bitmap>(cacheSize) { 
     protected int sizeOf(String key, Bitmap value) { 
      return value.getByteCount(); 
     } 
    }; 

В моем случае изображение составляет около 3 МБ и по меньшей мере 18 изображений, которые необходимо хранить в кеше. Это большой спрос со стороны телефона для хранения 60 МБ?

У меня есть попытка поймать код, почему приложение завершается?

+1

'изображение около 3MB', если это размер файла, это не имеет значения. что имеет значение при загрузке изображения в память, это размер растрового изображения: ширина х высота х глубина (обычно по 4 байт на пиксель по умолчанию) – njzk2

+0

А что, если размер растрового изображения большой? Что я могу сделать? –

ответ

2

Как этого избежать?

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

Однако, в общем, ваша проблема не имеет ничего общего с LRUCache и все, что связано с попытками сделать большие (~ 30 МБ) распределения. 31961104 байт, как Bitmap, эквивалентно 2826px изображением 2826px. Это намного больше, чем у большинства экранов Android. У вас может не быть одного непрерывного блока кучи для одного из тех, не говоря уже о 18. 18 может занимать больше памяти, чем у всего устройства, для младших Android-устройств.

Я хорошо понимаю, что 31 МБ является пределом использования памяти?

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

В моем случае изображение вокруг 3MB

Возможно, на диске есть. Большинство форматов файлов изображений сжимаются (PNG, JPEG, WebP, GIF и т. Д.). Количество используемого кучного пространства основывается на размере , декомпрессированном. Как отмечает njzk3, пространство кучи основано на разрешении (ширина x высота, в пикселях) и глубине бита (по умолчанию 4 байта на пиксель).

Что я могу сделать?

Использование меньшего растрового изображения.

Или не загружайте весь растровый файл в память, а используйте widgets, который может постепенно загружать изображение по мере необходимости на основе жесты панорамирования и масштабирования пользователя.

Смежные вопросы