直接上代码
缓存对象
import org.apache.log4j.Logger; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * 基于软引用实现的缓存,当内存不够使会自动释放缓存内容,以避免OOM * User: yfzhangbin * Date: 13-8-16 * Time: 下午4:02 */ public class SoftReferenceCache<K, V> { private static final Logger log = Logger.getLogger(SoftReferenceCache.class); private Map<K, InnerSoftReference<V>> cache; // 缓存对象池,<K, R->V> private ReferenceQueue<V> queue; // 引用队列,当GC执行后被回收的缓存对象的软引用将被入队,以方便从缓存池中清除失效的软引用。 private ReadWriteLock lock; // 读写锁 public SoftReferenceCache() { cache = new HashMap<K, InnerSoftReference<V>>(); queue = new ReferenceQueue<V>(); lock = new ReentrantReadWriteLock(false); } /** * 向缓存池中添加对象 * @param key * @param value */ public void put(K key, V value) { try { lock.writeLock().lock(); clearInvalidReference(); cache.put(key, new InnerSoftReference<V>(key, value, queue)); } finally { lock.writeLock().unlock(); } } /** * 从缓存池中获取对象 * @param key * @return */ public V get(K key) { try { lock.readLock().lock(); InnerSoftReference<V> softReference = cache.get(key); V v = null; if (softReference != null) v = softReference.get(); return v; } finally { lock.readLock().unlock(); } } /** * 从缓存池中清除失效的软引用 * 备注:失效软引用是指向null的引用 */ private void clearInvalidReference() { InnerSoftReference<V> softReference; while ((softReference = (InnerSoftReference)queue.poll()) != null) { if (softReference.get() == null) cache.remove(softReference.getKey()); } } /** * 缓存池中对象的个数 * @return */ public int size() { try { lock.readLock().lock(); int size = cache.size(); log.info(Thread.currentThread().getName() + " 缓存池中对象的个数: " + size); return size; } finally { lock.readLock().unlock(); } } /** * 清空缓存池,定时worker每次计算前调用此方法可清除历史记录 */ public void clearCache() { try { lock.writeLock().lock(); cache = new HashMap<K, InnerSoftReference<V>>(); queue = new ReferenceQueue<V>(); log.info(Thread.currentThread().getName() + "清空缓存池!"); } finally { lock.writeLock().unlock(); } } /** * 封装了软引用,便于获取对应缓存池中的key * @param <V> */ private class InnerSoftReference<V> extends SoftReference<V> { private K key; private InnerSoftReference(K key, V value, ReferenceQueue<V> queue) { super(value, queue); this.key = key; } public K getKey() { return key; } } }
测试类
import com.jd.recommend.service.util.*; import org.apache.log4j.Logger; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 测试类 * User: yfzhangbin * Date: 13-8-16 * Time: 下午5:18 */ public class TestSoftReferenceCache { private static final Logger log = Logger.getLogger(TestSoftReferenceCache.class); private static int MAX_COUNT = 100000; private static String KEY_PREFIX = "KEY_"; private static SoftReferenceCache<String, byte[]> cache = new SoftReferenceCache<String, byte[]>(); public static void main(String[] args) { ExecutorService es = Executors.newCachedThreadPool(); es.submit(new Customer()); es.submit(new Customer()); es.submit(new Customer()); es.submit(new Customer()); es.submit(new Customer()); es.shutdown(); } static class Customer implements Runnable { @Override public void run() { while (true) { for (int i = 0; i < MAX_COUNT; i ++) { byte[] a = cache.get(KEY_PREFIX + i); if (a == null) { a = new byte[1024]; cache.put(KEY_PREFIX + i, a); log.info(Thread.currentThread().getName() + " 向缓存池中添加对象[" + (KEY_PREFIX + i) + "]: " + a); } else { log.info(Thread.currentThread().getName() + " 从缓存池中获取对象[" + (KEY_PREFIX + i) + "]: " + a); } } } } } }
相关推荐
一个图片内存缓存和sdcard缓存的例子,经过很好的优化,性能很好,能有效的防止oom.
使用LruCache和DiskLruCache缓存资源,有效避免OOM,加载再多图片也不会顿卡,非常流畅,不会内存不够,到底有多牛谁运行谁知道。
很久没上传资源了,今天特意把自己收集的,自己用过的资源上传。Android 异步加载网络的图片,开始的时候显示默认的,当加载完成图片后替换掉原来的默认图片,绝对不会发生内存溢出的问题。
浏览网络大图,实现双缓存有效解决OOM问题
解决办法:对计算的表达式expression进行预编译,以表达式作为key,将编译好的类进行缓存,这样只会首次计算时去编译,后面再次计算时,根据expression从缓存里面取到对象,然后进行计算,不会再去创建类。...
Lru算法缓存解决图片OOM,一个比较好的解决方案
内存泄露:是指程序在申请内存后,无法释放已申请的内存空间就造成了内存泄露, 一次的内存泄露似乎不会有大的影响,但是内存泄露堆积的后果就是内存溢出 JMM 决定一个线程对共享变量的写入何时对另一个线程可见,...
SD卡,本地资源,网络图片的加载,使用缓存机制,防止OOM
简单实现Android开发中图片的三级缓存,避免OOM
android disklrucache实现图片三级缓存网上代码很多,我这里主要做了详细注释,以及做了代码检测checkstyle,findbugs,PMD
1、下载大图decode时,可根据View大小自动缩放图片,不在出现OOM和SkImageDecoder::Factory returned null错误 2、图片下载失败时,可自定义失败重试次数 3、记录正在下载的任务,防止屏幕滚动时多次下载 4、缓存...
瀑布流效果,带有图片缓存,避免OOM。
android端用于异步加载图片,内存缓存,文件缓存,imageview显示图片时增加淡入淡出动画。.zip Android高级图片滚动控件,3D版的图片轮播器Demo.rar GiF完美运行!!!!.rar ViewFlowTest 完美实现gallry轮训效果!...
图片三级缓存,优化内存使用,避免OOM
Android 异步加载图片缓存优化能异步加载图片,并缓存到本地,采用一级缓存,二级缓存和本地缓存,避免oom异常。源码中有详细注释,资料中有jar包,可以直接复制到项目中使用。
把图片缓存、手势及OOM三个主题放在一起,是因为在Android应用开发过程中,这三个问题经常是联系在一起的。首先,预览大图需要支持手势缩放,旋转,平移等操作;其次,图片在本地需要进行缓存,避免频繁访问网络;...
具体使用方法请看: http://blog.csdn.net/prophet_007/article/details/25031857 超级详细
imageloader加载本地图片,利用线程池,缓存,LIFO,防止大量图片加载导致OOM(代码中加有注释理解).rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
Android中图片的缩放处理,缓存处理,缓存包含http请求的缓存,内存缓存,磁盘缓存的处理等