Reputation: 2962
I have an image cache in my application which is implemented using SoftReferences. Dalvik starts applications with relatively small heap, and then increases it in case of demand. But I'd like to have my heap size bigger from the beginning. That is because when I already have some images in the cache, and an activity starts (for example) or other peak memory demand occurs, my cache gets purged in order to let memory for that peak demand. As a result, after the peak is gone I still have 2-3 MB of free space but my cache is empty!
The solution I see for this trouble is pre-allocating a bigger heap forehand so even with the peak consumption of 2-3 MBs it still has some roomspace so my SoftReferences are not purged.
I found that VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE)
would be helpful. In particular, Google uses that in their apps, as mentioned here. However, VMRuntime class is marked deprecated and said to be removed from the public API in a future release. So setMinimumHeapSize
is not a permanent solution.
How then I make Dalvik to grow my heap at startup?
Currently I use a really straight-forward and cheesy technique by just allocating a large array and releasing it. This makes Dalvik grow the heap as I want. However, I'm sure there must be more elegant way of doing that. Could you tell me that, please?
Upvotes: 16
Views: 19400
Reputation: 116332
you can't increase the heap size dynamically.
you can request to use more by using android:largeHeap="true" in the manifest, but you might not get any more heap size than normal, since it's only a request.
also, you can use native memory, so you actually bypass the heap size limitation.
here are some posts i've made about it:
and here's a library i've made for it:
Upvotes: 1
Reputation: 717
Instead of increasing heap size you can do some thing better. As you said that you are maintaining cache in you application which is implemented using SoftReferences. The best thing is to use LruCache you can do some thing like this:
private LruCache<String, Bitmap> bitmapCache;
final int memClass;
int cacheSize;
memClass = ((ActivityManager) context.getSystemService(
Context.ACTIVITY_SERVICE)).getMemoryClass();
Return the approximate per-application memory class of the current device. This gives you an idea of how hard a memory limit you should impose on your application to let the overall system work best. The returned value is in megabytes; the baseline Android memory class is 16 (which happens to be the Java heap limit of those devices); some device with more memory may return 24 or even higher numbers.
cacheSize = 1024 * 1024 * memClass / 10;
bitmapCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getHeight() * value.getRowBytes();
}
};
it will remove the bitmap images from LruCache if the memory exceeds the located memory to LruCache and load the new image in it.
Upvotes: 6
Reputation: 11272
If the cache is ususally small as you say, you can decide a valid footprint of your app by yourself and maintain your own cache without SoftReferences.
For example by a simple total byte counter: Just add or move any element used to the top of a list, add its size to the counter if it is new. Delete from the bottom if the total bytes exceed your rule-of-thumb limit, thereby decreasing your counter. Maybe the LinkedHashMap
class is useful for that: It can be used as a cache like a HashMap
, but it has an order too like a list.
Upvotes: 4
Reputation: 6322
The problem is that SoftReferences are useful for allocations done in the java heap space, but images are allocated natively, so this cache type won't really work on Android.
Upvotes: 2
Reputation: 10708
I don't think you can or are supposed to influence a device's memory at this level. Let the system do its thing and don't go against it. Do you need to hold such a big image cache with SoftReferences even when activities start?
You want to check how it is done in Shelves: see line 82 in http://code.google.com/p/shelves/source/browse/trunk/Shelves/src/org/curiouscreature/android/shelves/util/ImageUtilities.java?r=26
Upvotes: 0