Казалось бы, непоследовательные сбои на различных устройствах Android
-
26-10-2019 - |
Вопрос
Я делаю игру, которая должна загружать все растровые карты в начале, потому что в встроенном редакторе игры пользователь может поместить любой из спрайтов на уровень. Также уровни используют различные спрайты без какой -либо системы, которая позволила бы динамически загружать группы спрайтов для каждого уровня.
Через некоторое время в игре уже более 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 и выделяя прямо из ОС. Это огромный взлом, и мост между Далвиком и вашим распределением будет довольно уродливым.
Другие советы
Сначала вам нужно найти то, что именно использует всю вашу память. Проверь это. Возможно, например, вы могли бы переработать растровые карты.