У меня есть исключение 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.
Большое спасибо
Meymann
Думаю, в вашем случае нет ничего особенного. Просто не хватает памяти. У вас не может быть в памяти несколько растровых изображений 600x800, они занимают слишком много памяти. Вы должны сохранить их на SD и загрузить в память по запросу. Я думаю, это именно то, что вы делаете.
Вы должны знать одну вещь: DDMS отображает потребление памяти кучи java. Но есть еще и собственная память, которая не отображается в DDMS. И растровые изображения, насколько я понимаю, создаются в родной памяти. Так что DDMS - просто плохой инструмент для отслеживания этих проблем с памятью.Вам просто нужно убедиться, что вы освободили свою память, что изображения собираются сборщиком мусора после того, как они вам больше не нужны.
Сборщик мусора работает по собственному графику. Вот почему вы должны вызывать метод Bitmap.recycle () для растровых изображений, которые вам больше не нужны. Этот метод освобождает именно ту внутреннюю память, которая у вас закончилась. Таким образом, вы не зависите от GC и сможете как можно скорее освободить самый большой кусок памяти.
Прежде всего, вы должны убедиться, что у вас нет утечки растровых изображений.
Вот хороший пост о распределении памяти, он может помочь вам копнуть глубже
Не уверен, подходит ли вам этот вариант, но пробовали ли вы использовать суперсэмплинг изображений Странная проблема нехватки памяти при загрузке изображения в объект Bitmap ?