2013-07-27 2 views
0

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

Я использую LRUCache для хранения Android Bitmap объектов с ключами Integer. Проблема в том, что когда я пытаюсь сохранить Bitmap в LRUCache с ключом примитивного типа int, объект Integer выделяет память Integer.valueOf(int), чтобы преобразовать примитивное целое в эквивалент объекта Integer.

Все это хорошо, но это вызывает одновременную сборку мусора во время рендеринга графики моей основной петли моей игры, что приводит к снижению частоты кадров, что создает заметную задержку так часто, когда происходит эта сборка мусора. Ниже приведена часть моего журнала, в котором измеряется время, необходимое для рендеринга графики. Мой метод визуализации в значительной степени зависит от использования нагрузки Bitmap объектов от LRUCache, так что понятно, почему это вызывает задержку, как показано ниже, когда распределение, вероятно, происходит довольно часто:

07-27 17:55:41.418: W/Render(13937): Time: 28ms 
07-27 17:55:41.438: W/Render(13937): Time: 28ms 
07-27 17:55:41.468: W/Render(13937): Time: 29ms 
07-27 17:55:41.498: W/Render(13937): Time: 29ms 
07-27 17:55:41.528: D/dalvikvm(13937): GC_CONCURRENT freed 384K, 13% free 17265K/19756K, paused 3ms+1ms, total 17ms 
07-27 17:55:41.548: W/Render(13937): Time: 44ms 
07-27 17:55:41.578: W/Render(13937): Time: 27ms 
07-27 17:55:41.608: W/Render(13937): Time: 28ms 
07-27 17:55:41.628: W/Render(13937): Time: 28ms 
07-27 17:55:41.658: W/Render(13937): Time: 29ms 

Есть ли способ обойти Integer.valueOf(int) Выделение памяти в моем приложении? Или есть альтернатива LRUCache, которая принимает примитивные типы, такие как int?

ответ

0

Я не знаю кэша Java, который использует примитивные int ключи, но это не должно быть слишком трудно изменить кэш с открытым исходным кодом (например, Guava): удалить «инвентарем Map» заявление, заменить все K с с int s и заменить все V s с Object s (у меня нет исходного кода передо мной, но каждый кеш Java, который я когда-либо видел, это всего лишь Map<K, V> плюс некоторая логика для выселения). Вам также потребуется заменить вызов на key.hashCode() с помощью встроенной функции хэша (просто найдите Google для соответствующего, вы можете получить недорогой номер с abs(key * prime_number) modulo size_of_backing_array).

0

Я создал новую коллекцию примитивных коллекций с открытым исходным кодом под названием Banana, которую вы можете использовать. Существует LRU class, который имеет примитивные длинные ключи. Поддерживаемые данные - это int, long или Java Object - это то, что вам нужно. Обратите внимание, что бананы, как правило, не являются потокобезопасными, поэтому обязательно синхронизируйте их соответствующим образом.

PS: Проект все еще находится на ранней стадии, и я не сделал официального релиза. API может измениться в будущем.

Кстати, проверьте другие классы, такие как BlockAllocator, и примитивные связанные списки и карты, я думаю, что они особенно полезны для Java-разработчиков игр.