Казалось бы, непоследовательные сбои на различных устройствах Android

StackOverflow https://stackoverflow.com/questions/7809909

Вопрос

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

Через некоторое время в игре уже более 250 изображений PNG с общим размером 3,5 МБ.

Игра загружает большинство спрайтов (около 200), используя Bitmapfactory.decodestream без каких -либо набора параметров, а также есть около 50 других, на которые упоминаются в макетах XML.

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

Телефон, на котором я разработал, HTC Desire с Android 2.2 24MB VM -размер, никогда не работает.

Dell Streak с размером VM Android 2.2 и 40 МБ тоже никогда не работает.

Motorola Milestone с Android 2.1 и 24MB VM -размер успешно загружает все спрайты, но задыхается на несколько последних изображений, используемых в ImageView, при запуске одного из видов деятельности (Start Menu). Если я прокомментирую несколько таких изображений, он загружается ОК, но может задушить одно из других действий позже. Это также не стабильно, вероятно, потому что фрагментация происходит по -разному в разных запусках.

HTC Hero с 2,2 моего приятеля (не знаю размер кучи, это также 16 МБ?) Также.

Что наиболее запутанно, так это то, что у Motorola 24 МБ, так же, как HTC Desire. 2.1 Реализует управление памятью менее эффективной? (Например, приводит к большей фрагментации?) Или управление памятью хуже всех телефонов Motorola? Тогда почему HTC Hero с 2,2 Crash? Что больше в желании HTC, чем HTC Hero?

Похоже, OOM случается на более старых телефонах, но это единственное, что я выяснил до сих пор.

Если OOM происходит только на более старых телефонах, которые, скажем, 5% рынка, я могу просто исключить 2.1 или более конкретный список из поддерживаемых устройств, просто собрав отчеты об аварии и исключая все, что разбилось из списка поддерживаемых. В противном случае мне теперь нужно уменьшить все мои изображения с некоторым постоянным фактором (например, 1.6), что означало бы изменение размера всех 45 уровней, которые потребовались дни и дни проектирования и тестирования, перемещение элементов графического интерфейса и т. Д. Даже после этого я ' D все еще не будьте уверены, на каких устройствах снижение общего размера растровых карт в коэффициенте, например, 2, достаточно, чтобы избежать OOM.

Есть советы по этому поводу? Должен ли я установить какие -либо конкретные параметры для Bitmapfactory? Кстати, большинство изображений имеют прозрачные пиксели BG, которые, насколько я понимаю, не позволяет получить их в формате 565.

Я провел 2 дня, просматривая здесь и в других местах, но все еще в недовольстве.

Спасибо.

Это было полезно?

Решение

Мне пришлось разобраться с более простой версией вашей проблемы - у нас было 3 2 -миллионного слоя друг на друга, что, что неудивительно, иногда вызывало OOM.

В моем случае, вместо того, чтобы использовать 3 изображения друг на друга, все время оставляя все 6 MPIX в памяти, я вручную смешивал слои, тем самым сохраняя не более 4 MPIX в памяти в любое время (и только 2 MPIX в " Отдых » - слои изменились в нашем приложении).

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

Что касается непоследовательных OOMS, это, вероятно, связано с сборкой мусора. Вы можете предположить, что сборщик мусора является неэнергинистичным, и, следовательно, любое давление памяти также становится нетерминированным (в зависимости от того, когда GC в последний раз начал).

Краткое резюме заключается в том, что вы должны быть очень, очень осторожны с использованием памяти, и обойти его. *

* Теоретически, вы можете выделить память за пределами кучи Далвика, используя NDK и выделяя прямо из ОС. Это огромный взлом, и мост между Далвиком и вашим распределением будет довольно уродливым.

Другие советы

Сначала вам нужно найти то, что именно использует всю вашу память. Проверь это. Возможно, например, вы могли бы переработать растровые карты.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top