1

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?

Community
  • 1
  • 1
Chumper
  • 13
  • 2
  • 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. – Stefan Haustein Apr 27 '13 at 11:19
  • That was the way i tried next, to get a number based on the given numbers. That also looks good, it will cause less often the GC to kick in. I think this is a good way, but one question: Why do we convert the int still one more time to int with valueOf? You said because of the internal cache? – Chumper Apr 27 '13 at 11:45
  • Actually Java will call valueOf() automatically when auto-boxing in implicit conversions. I just wanted to point out that one should not use new Integer() to convert from 'int' to 'Integer'. – Stefan Haustein Apr 27 '13 at 11:56
  • Thanks so far, that was easier than i thought... I use the formular slightly different with a sparse array now and i don't have any problems so far. If you don'T mind, you can answer the question and i will close this then. Thanks – Chumper Apr 27 '13 at 12:16

1 Answers1

0

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().

Stefan Haustein
  • 18,427
  • 3
  • 36
  • 51