English 中文(简体)
采用软背对 Android的 Bit子
原标题:Using SoftReference to cache Bitmap on Android cause OOM

我正在开发一个需要装上比图的申请。 并使用<代码>SoftReference。 我将每一条软性参考与<代码>ReferenceQueue联系起来,并用一个散列图进入。 SoftReference。 如下所示:

public static class MemCache {

    final private ReferenceQueue<Bitmap> queue = new ReferenceQueue<Bitmap>();
    private Map<String, SoftReference<Bitmap>> hash = null;

    public MemCache() {
        hash = Collections.synchronizedMap(
            new LinkedHashMap<String, SoftReference<Bitmap>>()
        );
    }

    public synchronized Bitmap put(String key, Bitmap value) {
        clean();
        SoftReference<Bitmap> ref = new SoftReference<Bitmap>(value, queue);
        SoftReference<Bitmap> res = hash.put(key, ref);
        if (res == null) return null;
        return res.get();
    }

    public synchronized Bitmap get(Object key) {
        clean();
        SoftReference<Bitmap> ref = hash.get(key);
        if (ref == null) return null;
        Bitmap val = ref.get();
        if (val != null) return val;
        hash.remove(key);
        return null;
    }
}

然后,在我撰写<代码>clean()时,如:

    private synchronized void clean() {
        Reference<? extends Bitmap> sv;
        while ((sv = queue.poll()) != null)
            hash.remove(sv);
        Queue<String> toRemove = new LinkedList<String>();
        for(Entry<String, SoftReference<Bitmap>> e : hash.entrySet()){
            if(e.getValue()==null) continue;
            if(e.getValue().get()==null) 
                toRemove.add(e.getKey());
        }
        String s;
        while((s = toRemove.poll())!= null)
            hash.remove(s);
        Log.e("ImageCacheManager", "MemCache Size/2:" + new String(new char[hash.size() / 2]).replace("", "="));
    }

Which check all the SoftReferences in the hash table for not null. The memcache appears good, but if I only wrote:

    private synchronized void clean() {
        Reference<? extends Bitmap> sv;
        while ((sv = queue.poll()) != null)
            hash.remove(sv);
        Log.e("ImageCacheManager", "MemCache Size/2:" + new String(new char[hash.size() / 2]).replace("", "="));
    }

Which only remove the element been put into ReferenceQueue The Log then will print more and more =, even there is some decrease, the tendency is increase

http://www.ibm.com/developerworks/library/j-refs/“rel=“nofollow”http://www.ibm.com/developerwork/library/j-refs/

The referent of the SoftReference is set to null. But most of the SoftReference was not in ReferenceQueue. Just between the state that the object is marked as finalizable but not be finalized? Will the Bitmap marked as finalizable but not be finalized been recycled?

最佳回答

I have experimented a similar issue. After sometime I had realized that is because of the way android manage bitmap. If I have not misunderstood they use "skia", a native implementation, for bitmap. So bitmaps are not allocated in the java heap but in the native heap and the java bitmap object itself is really small and a poor candidate for GC. So they provided the recycle method that free the native memory retained by a bitmap.

Sorry for my poor english.

问题回答

暂无回答




相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签