Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
Posts: 35
Registered: ‎03-08-2009
My Device: Not Specified

Memory Cache

I have been working on implementing a memory cache, and now looking for some insight/guidance on best practices.  I have a base class that I use for a cache which resides in the runtimestore:

 

import java.util.Hashtable;
import net.rim.device.api.lowmemory.LowMemoryListener;

public class BaseMemoryCache extends Hashtable implements LowMemoryListener {
    
    public BaseMemoryCache () {
        super();
    }

    public boolean put (String key, Object value) {
        try {
            super.put(key, value);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    public Object get (String key) {
        return super.get(key);
    }
   
    
    public boolean freeStaleObject(int priority) {
        System.out.println("*** LM Received, clearing cache...");
        super.clear();
        return true;
    }
    
}

 

Rather than waiting for the object to receive the lowmemory notification, how can I best control the size ? I have tried wrapping the values in weak references, but they are cleared too quickly for the cache to be of any use (SoftReferences anyone?).  Can anyone provide an example of applying size constraints (in bytes)? I started to create one (based on above), but it involved a nested "reference table" for storing value sizes (in bytes) and insert date, and a "Janitor" thread for cleaning things up based on cache size (and remove value based on eldest).  It was getting too complicated it seemed.  There must be a better way? 

 

(I'm targeting +5.x)

Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: Memory Cache

What sort of things are you trying to cache?  And why are you trying to cache them?

 

I think the appropriate design depends on the data to be cached.

 

The sort of things that I think are worthwhile caching are assets that you download from the web, so these are usually available as byte arrays.  IN which case you might consider have a backing store on SD Card, plus weak references to the actual Object involved.  Then when a subsequent request comes in, you look at the weak reference and use it if present, otherwise reload from SD Card. 

 

Also be very careful about the use of RuntimeStore as it is retained when you app is not running.  You can use your Application 'class' as a hook for this storage, then it disappears when your application disappears. 

Highlighted
Developer
Posts: 35
Registered: ‎03-08-2009
My Device: Not Specified

Re: Memory Cache

Images (well byte[]).  I was testing reducing network I/O (seemed like the very Blackberry thing to do) by storing the byte[] as the value (initially I tested having the value wrapped in a weak reference) and using the image URL as the key.  For those with an SDCard have an "extended" version, for those without, extremely limited. Then for a network request, it would test the cache then proceed with the request if necessary.   There was no need to persist between app sessions (simply "escaping" out of the application only requested background), and when exited I'm destroying the object in the store (RuntimeStore.getRuntimeStore().remove(MY_LONG)).  It worked well.  But obviously without any constraints it can grow and "takeover" the device when active.  I guess the better question is, how to enforce size of a hashtable?  Any solid examples?  Like I mentioned previously, my approach of reference objects to track cache (hashtable) size (in bytes), and value insert dates, then a separate thread to enforce seemed a bit convoluted.  I was looking for something a bit more...inherent.  Eventually the idea is to give someone the ability to specific cache size in settings.  Thanks.