Search code examples
javaandroidstringcachingstringbuffer

Avoid String Allocation while using a LRU Cache


I use a LRU and a disk cache to cache some images in the memory and on the disk. Previously I used

private LruCache<String, Bitmap> mMemoryCache;

to save the images but as I watch the allocation stack I see a lot of String allocations which is clear to me because everytime i use mMemoryCache.get(cs); it will allocate a new String object.

During my drawing of each bitmap i need to use the cache around 50-100 times each frame with will cause a lot of GC because of the short living strings.

How can i prevent this?

I looked at other questions on how to prevent String allocations, like this one and I use the solution by David for the Debug FPS showing, but i cant use it for this special cache version.

I split every image into 100x100 tiles, my Cache keys will look like this pageNumber-withcount-heightcount-zoomfactor

I tried using a StringBuffer but that will not work as toString() will allocate a new String and I need to compare the content. I could try to use a int/float with 000 as replacement for "-" or even work with a char[] array inside my cache class, but what is the best way to do this?


Solution

  • Why not use an Integer as the cache key and calculate it as follows (assuming the zoomfactor is < 100, too):

    int keyInt = (((pageNumber * 100 + withcount) * 100) + 
                  heightcount) * 100 + zoomfactor;
    Integer key = Integer.valueOf(keyInt);
    

    This will still allocate objects, but Integer.valueOf has a cache for some of them already, and the objects will be smaller. An auto-boxing will also use Integer.valueOf (which doesn't create a new instance for small numbers), just avoid new Integer().