На первый взгляд несовместимые сбои OutOfMemory на разных устройствах Android - PullRequest
1 голос
/ 18 октября 2011

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

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

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

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

Телефон, на котором яРазработано HTC HTC с Android 2.2. Размер кучи виртуальной машины 24 МБ никогда не запускает OOM.

Dell Streak с Android 2.2 и 40 МБ Размер кучи виртуальной машины тоже не работает OOM.

Motorola Milestone с Android 2.1 и 24 МБРазмер кучи виртуальной машины успешно загружает все спрайты, но затягивает несколько последних изображений, используемых в ImageView, при запуске одного из действий (меню «Пуск»).Если я закомментирую несколько таких ImageViews, он загрузится нормально, но позже может подавиться одним из других действий.Это также не стабильно, вероятно, потому что фрагментация происходит по-разному в разных запусках.

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

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

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

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

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

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

Спасибо.

Ответы [ 2 ]

1 голос
/ 18 октября 2011

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

1 голос
/ 18 октября 2011

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

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

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

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

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

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

...