Я настраиваю интерактивные игры на Java для платформы Android. Время от времени появляется икота при рисовании и взаимодействии для сбора мусора. Обычно это менее одной десятой секунды, но иногда она может достигать 200 мс на очень медленных устройствах.
Я использую профилировщик ddms (часть Android SDK) для поиска, откуда берутся мои выделения памяти, и изгоняю их из моего внутреннего рисования и логических циклов.
Худшим нарушителем были короткие петли, сделанные, например,
for(GameObject gob : interactiveObjects)
gob.onDraw(canvas);
где каждый раз, когда цикл выполнялся, выделялся iterator
. Я использую массивы (ArrayList
) для моих объектов. Если я когда-либо захочу деревья или хеши во внутреннем цикле, я знаю, что мне нужно быть осторожным или даже переопределять их, вместо использования инфраструктуры Java Collections, поскольку я не могу позволить себе дополнительную сборку мусора. Это может возникнуть, когда я смотрю приоритетные очереди.
У меня также есть проблемы, когда я хочу отображать оценки и прогресс, используя Canvas.drawText
. Это плохо,
canvas.drawText("Your score is: " + Score.points, x, y, paint);
потому что Strings
, char
массивы и StringBuffers
будут распределены по всему, чтобы они работали. Если у вас есть несколько элементов отображения текста и запустите фрейм 60 раз в секунду, который начинает складываться и увеличит ваши икоты сбора мусора. Я думаю, что лучший выбор здесь - сохранить массивы char[]
и декодировать ваши int
или double
вручную в него и объединить строки в начало и конец. Я хотел бы услышать, если там что-то более чистое.
Я знаю, что там должны быть другие, которые занимаются этим. Как вы справляетесь с этим, и каковы подводные камни и лучшие практики, которые вы обнаружили для интерактивного запуска на Java или Android? Эти проблемы с gc достаточно, чтобы я пропустил ручное управление памятью, но не очень.