Android: OutofMemoryError: растровый размер превышает бюджет VM без причины I, видят

У меня есть исключение OutOfMemory с галереей более чем 600x800 пикселей JPEG.


Среда

Я использовал Галерею с изображениями JPG приблизительно 600x800 пикселей.

Так как мое содержание может быть немного более сложным, чем просто изображения, я установил каждое представление, чтобы быть RelativeLayout, который переносит ImageView с JPG.

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

Платформа

Я использую AVD 256 RAM и 128 Размеров "кучи", с 600x800 экран. Это также происходит на Граничной цели Entourage, за исключением того, что с устройством более трудно отладить.


Проблема

Я получал исключение:

OutofMemoryError: bitmap size exceeds VM budget

И это происходит при выборке пятого изображения. Я попытался изменить размер своего кэша изображений, и это - все еще то же.


Странная вещь: не должно быть проблемы памяти

Чтобы удостовериться, что предел "кучи" очень далеко, от какого мне нужно, я определил фиктивный массив 8 МБ в начале и оставил его не имеющим ссылки, таким образом, он сразу диспетчеризируется. Это - член потока действия и определяется как после

static { @SuppressWarnings("unused")
byte dummy[] = new byte[ 8*1024*1024 ]; }    

Результат состоит в том, что размер "кучи" составляет почти 11 МБ, и это все бесплатно. Обратите внимание, что я добавил, что прием после того, как он начал отказывать. Это делает OutOfMemory менее частым.

Теперь, я использую DDMS. Непосредственно перед катастрофическим отказом (не изменяется очень после катастрофического отказа), шоу DDMS:

ID  Heap Size   Allocated   Free       %Used    #Objects
1   11.195 MB   2.428 MB    8.767 MB   21.69%   47,156  

И в таблице детали это показывает:

Type  Count  Total Size   Smallest   Largest   Median    Average
free  1,536  8.739MB      16B        7.750MB   24B       5.825KB

Самый большой блок составляет 7.7 МБ. И все же LogCat заявляет:

ERROR/dalvikvm-heap(1923): 925200-byte external allocation too large for this process.

При возражении против отношения медианы и среднего числа вероятно предположить, что большинство доступных блоков является очень маленьким. Однако существует блок, достаточно большой для битового массива, это 7.7M. Каким образом это все еще не достаточно?

Примечание: Я записал трассировку "кучи". При рассмотрении выделенного объема данных не такое чувство, что больше, чем 2M выделяются. Это действительно соответствует отчету о свободной памяти DDMS.


  • Могло случиться так, что я испытываю некоторую проблему как фрагментация "кучи"?
  • Как я решаю/обходным решение проблему?
  • "Куча" совместно используется ко всем потокам?
  • Могло случиться так, что я интерпретирую считывание DDMS неправильным способом, и существует действительно блок № 900K для выделения? Если так, кто-либо может сказать мне, где я вижу это?

Большое спасибо

Meymann

34
задан Meymann 14 June 2010 в 12:20
поделиться

2 ответа

Думаю, в вашем случае нет ничего особенного. Просто не хватает памяти. У вас не может быть в памяти несколько растровых изображений 600x800, они занимают слишком много памяти. Вы должны сохранить их на SD и загрузить в память по запросу. Я думаю, это именно то, что вы делаете.

Вы должны знать одну вещь: DDMS отображает потребление памяти кучи java. Но есть еще и собственная память, которая не отображается в DDMS. И растровые изображения, насколько я понимаю, создаются в родной памяти. Так что DDMS - просто плохой инструмент для отслеживания этих проблем с памятью.Вам просто нужно убедиться, что вы освободили свою память, что изображения собираются сборщиком мусора после того, как они вам больше не нужны.

Сборщик мусора работает по собственному графику. Вот почему вы должны вызывать метод Bitmap.recycle () для растровых изображений, которые вам больше не нужны. Этот метод освобождает именно ту внутреннюю память, которая у вас закончилась. Таким образом, вы не зависите от GC и сможете как можно скорее освободить самый большой кусок памяти.

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

Вот хороший пост о распределении памяти, он может помочь вам копнуть глубже

12
ответ дан 27 November 2019 в 17:16
поделиться

Не уверен, подходит ли вам этот вариант, но пробовали ли вы использовать суперсэмплинг изображений Странная проблема нехватки памяти при загрузке изображения в объект Bitmap ?

5
ответ дан 27 November 2019 в 17:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: