Smart Image cache

I have been thinking of ways to improve my image cache.

Currently I a WeakHashMap which maps an ID to an image.
If the ID isn’t in the map it will load that image and then save it to the map.
The problem is that multiples of the same images will be stored in memory.
Say its loading images from an unknown source, and so can’t improve it before this.

I’m trying to figure out a way to check after loading the image that if the same image is already in the image cache and use that instead. I guess a way would have 2 WeakHashMaps, one to map which does the id to the image and the other to do the imageID to the image.

I guess my problem is what would be the best way to get an image ID which is always the same for the same image.

WeakHashMap is the worst choice for a RAM cache… you really need a SoftHashMap, but Sun didn’t make one.

WeakHashMaps are ‘flushed’ every GC, which can run up to several times per second, making them useless to do any kind of caching.

SoftHashMaps are ‘flushed’ every FULL GC, most likely to occur when the heap fills up, which is when you want your cache to be cleared.

[quote]SoftHashMaps are ‘flushed’ every FULL GC, most likely to occur when the heap fills up, which is when you want your cache to be cleared.
[/quote]
Ah thanks for pointing that one out. I’ll see if I can find a SoftHashMap later.

Edit: Replaced it with a LRUMap, seemed to fix a broken image problem that I was having :slight_smile:

Hi,

I’ve been looking at caching recently in my own stuff, and I’m not entirely sure I agree with Riven’s assessment. :persecutioncomplex:

IMO, WeakHashMap may be fine for your cache (I’ll get to that), but the main thing is that it’s the image that should be wrapped in the SoftReference - ie. the value in the Map, not the key. You could even get away with a standard HashMap<ID, SoftReference> for that.

The use of a WeakHashMap, SoftHashMap or LRUMap could deal with the IDs themselves. If your IDs are unique objects, then a WeakHashMap would be fine as once you have no reference to the ID, there’s no way you can retrieve the image anyway. If you’re using Strings, URIs or anything else that overrides equals() though, you’d be better off with the LRUMap I would think. However, either way I’d wrap the images in a SoftReference - then you know there’ll be cleared if you run out of memory, even if you have a strong reference to the ID.

Best wishes, Neil

Well, the javadoc is pretty clear about when SoftReference, WeakReference (and PhantomReference) ought to be garbage collected.

Surely you might use a regular Map with SoftReference values, instead of a SoftHashMap. The only thing you have to remember is not to use WeakHashMap for caching if you want to take advantage of the space on the heap as long as possible.

Yeah, not disagreeing with you here.

This is the bit I don’t agree with. A SoftHashMap (has SoftReference keys) and a Map with SoftReference values are completely different things. You’re likely to keep strong references to the ID in all components that use the image - if the SoftReference was on the ID, it would never be GC’d before you ran out of memory. A WeakHashMap would be fine in the specific scenario I mentioned, where when the ID has disappeared there’s no way to get the image anyway.