0

I'm developing a game for the Android mobile platform, and everything is going great. However, I'm at a point where'd I'd like to address a few problems I've noticed whilst I've been developing and have ignored until now.

I'm using an LRUCache to store Android Bitmap objects with Integer keys. The problem is, when I attempt to store a Bitmap in the LRUCache with a key of primitive type int, the Integer object allocates memory with Integer.valueOf(int) to convert the primitive integer to the Integer object equivalent.

This is all well and good, but it causes concurrent garbage collection during the graphics rendering part of my main loop of my game, causing a drop in frame rate which creates a noticeable lag every so often when this garbage collection occurs. Below is a portion of my log which measures the time taken for graphics rendering to occur. My rendering method relies heavily on the use of loading Bitmap objects from the LRUCache, so it's understandable why it causes a delay like below when allocation is likely to be occurring quite frequently:

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

Is there any way around Integer.valueOf(int) allocating memory in my application? Or is there an alternative to an LRUCache which accepts primitive types such as int?

Kavan
  • 340
  • 2
  • 12

2 Answers2

0

I am not aware of a Java cache that uses primitive int keys, but it shouldn't be too difficult to modify an open source cache (eg Guava): remove the "implements Map" statement, replace all Ks with ints, and replace all Vs with Objects (I don't have the source code in front of me, but every Java cache I've I've ever seen is just a Map<K, V> plus some logic for eviction). You will also need to replace the call to key.hashCode() with an inlined hash function (just search Google for an appropriate one, you can get an inexpensive one with abs(key * prime_number) modulo size_of_backing_array).

Zim-Zam O'Pootertoot
  • 17,888
  • 4
  • 41
  • 69
0

I have created a new open source primitive collections library called Banana which you can use. There is an LRU class there which has primitive long keys. Supported data is an int, a long or a Java Object - which is what you need. Note that Banana is generally not thread safe so be sure to synchronize appropriately.

PS: The project is still at an early stage and I did not made my official release. API may change in the future.

By the way, check out other classes like BlockAllocator, and the primitive linked lists and maps, I think they are particularly useful for Java game writers.

Omry Yadan
  • 31,280
  • 18
  • 64
  • 87