`
wangxuliangboy
  • 浏览: 210703 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

SoftReference(利用软引用写的一个简单HashMap)

阅读更多

软引用对象,在响应内存需要时,由垃圾回收器决定是否清除此对象。软引用对象最常用于实现内存敏感的缓存

软可到达对象的所有软引用都要保证在虚拟机抛出 OutOfMemoryError 之前已经被清除。

只要软引用的指示对象是强可到达对象,即正在实际使用的对象,就不会清除软引用

public class SoftHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V> {

    private static final int        DEFAULT_INITIAL_CAPACITY = 16;
    private static final int        MAXIMUM_CAPACITY         = 1 << 30;
    private Entry[]                 table;
    private final ReferenceQueue<K> queue                    = new ReferenceQueue<K>();
    private static final Object     NULL_KEY                 = new Object();
    private int                     size;

    public SoftHashMap() {
        table = new Entry[DEFAULT_INITIAL_CAPACITY];
    }

    /**
     * @param key
     * @param value
     * @return
     */
    @SuppressWarnings("unchecked")
    public V put(K key, V value) {
        Entry[] tab = getTable();
        Entry temp;
        for (int j = 0; j < tab.length; j++) {
            temp = tab[j];
            if (temp == null) continue;
            V oldKey = (V) temp.getKey();
            if (key == oldKey) {
                temp.setValue(value);
                return (V) temp.getValue();
            }
            temp = null;
        }

        tab[size] = new Entry<K, V>(key, value, queue);
        if (++size >= table.length) resize(table.length << 1);
        return value;
    }

    /**
     * @param newCapacity
     */
    void resize(int newCapacity) {
        Entry[] newTable = new Entry[newCapacity];
        System.arraycopy(table, 0, newTable, 0, newTable.length);
        table = newTable;
    }

    /**
     * @param h
     * @param length
     * @return
     */
    static int indexFor(int h, int length) {
        return h & (length - 1);
    }

    /**
     * @param key
     * @return
     */
    private int hash(Object key) {
        return key.hashCode() & table.length;
    }

    /**
     * @return
     */
    private Entry[] getTable() {
        expungeStaleEntries();
        return table;
    }

    /**
     *
     */
    private void expungeStaleEntries() {
        Entry<K, V> e;
        while ((e = (Entry<K, V>) queue.poll()) != null) {
            e = null;
            size--;
        }
    }

    /**
     * @param key
     * @return
     */
    private static Object maskNull(Object key) {
        return (key == null ? NULL_KEY : key);
    }

    /**
     * @return
     */
    public Set<java.util.Map.Entry<K, V>> entrySet() {
        expungeStaleEntries();
        Set<Map.Entry<K, V>> entrys = new HashSet<Map.Entry<K, V>>();
        for (int i = 0; i < table.length; i++) {
            if (table[i] == null) continue;
            entrys.add(table[i]);
        }
        return entrys;
    }

 

  public String toString(){

            return entrySet().toString();

  }

 

 

    private static class Entry<K, V> extends SoftReference<K> implements Map.Entry<K, V> {

        private V value;

        public Entry(K k, V v, ReferenceQueue queue) {
            super(k, queue);
            this.value = v;
        }

        public K getKey() {
            return super.get();
        }

        public V getValue() {
            return value;
        }

        public V setValue(V value) {
            V oldvalue = value;
            this.value = value;
            return oldvalue;
        }

        public boolean equals(Object o) {
            if (!(o instanceof Map.Entry)) return false;
            Map.Entry e = (Map.Entry) o;
            Object k1 = getKey();
            Object k2 = e.getKey();
            if (k1 == k2 || (k1 != null && k1.equals(k2))) {
                Object v1 = getValue();
                Object v2 = e.getValue();
                if (v1 == v2 || (v1 != null && v1.equals(v2))) return true;
            }
            return false;
        }

        public int hashCode() {
            Object k = getKey();
            Object v = getValue();
            return ((k == null ? 0 : k.hashCode()) ^ (v == null ? 0 : v.hashCode()));
        }

        public String toString() {
            return getKey() + "=" + getValue();
        }
    }

    public static void main(String[] args) throws Exception {
        SoftHashMap<Object, Object> softHashMap = new SoftHashMap<Object, Object>();
        Object key1 = new String("asdfasdf"); // 堆中的对象是可以被垃圾回收的,而栈中基本变量,引用变量,是在跳出所在的语句块时!
        // 基本类型变量或对象变量所在栈内存被系统自动释放!并且内存空间能够立即被释放!
        // Object key1 = "sadfasdf";

        Object value1 = "B";
        Object key2 = "D"; // 栈变量是不会被垃圾回收器收集的
        Object value2 = "B";
        Object key3 = "C";
        Object value3 = "B";

        softHashMap.put(key1, value1);
        softHashMap.put(key2, value2);
        softHashMap.put(key3, value3);
        softHashMap.put(key3, "asdfadfasd");
        key3 = null;
        // key2 = null;
        // key1 = null;
        System.gc();
        Thread.sleep(1000);
        Set<Map.Entry<Object, Object>> set = softHashMap.entrySet();
        for (Map.Entry<Object, Object> entry : set) {
            System.out.println("===" + entry.getValue());
        }

    }
}

分享到:
评论
1 楼 raymond2006k 2010-01-30  
还没仔细看,不过很不错,很需要这个。

相关推荐

    基于软引用实现的缓存,当内存不够使会自动释放缓存内容,以避免OOM

    通常,我们会创建一个软引用对象,将实际的缓存数据作为参数传入,然后将软引用对象放入一个映射结构(如HashMap)中。当需要访问缓存时,首先检查映射中是否存在对应的软引用,如果存在,则尝试通过软引用获取实际...

    Android基于SoftReference缓存图片的方法

    // 创建一个HashMap用于存储软引用的Bitmap对象 Map, SoftReference&lt;Bitmap&gt;&gt; imageCache = new HashMap(); // 加载图片到Bitmap对象 Bitmap bitmap = BitmapFactory.decodeStream(inputStream); // 创建...

    解析Android开发优化之:软引用与弱引用的应用

    通过创建一个`SoftReference&lt;Bitmap&gt;`实例并将Bitmap对象保存在`HashMap`中,我们可以在需要时快速访问图片,而当内存紧张时,软引用的对象会被自动清理,防止内存溢出。 软引用可以与`ReferenceQueue`一起使用,当...

    ListView异步加载网络图片

    这个类通常包含一个HashMap来存储URL与SoftReference的映射关系。 2. 当需要加载图片时,首先检查HashMap中是否存在对应的SoftReference。如果存在且Bitmap未被回收,直接返回Bitmap;否则,启动一个新的后台任务...

    ListView异步加载图片

    1. 创建图片缓存类:创建一个缓存类,例如`BitmapCache`,它包含一个SoftReference数组或者使用HashMap存储SoftReference。这样可以存储图片对象,同时允许在内存紧张时释放缓存。 2. 实现异步加载:使用AsyncTask...

    内存泄露从入门到精通三部曲之常见原因与用户实践1

    为避免这个问题,可以使用弱引用(WeakReference)或软引用(SoftReference)来引用外部对象,或者在适当时候手动释放引用。 在Android开发中,组件的生命周期管理至关重要。BroadcastReceiver、ContentObserver、...

    高速缓存实现源码

    本项目通过源码实现了一个简单的高速缓存,展示了其在多线程并发环境下的性能优势。 在Java中,高速缓存的实现通常依赖于数据结构如哈希表(HashMap)或并发容器如ConcurrentHashMap。哈希表提供快速的查找和插入...

    Android实现ListView异步加载图片

    1. **缓存管理**:首先,类中定义了一个`HashMap`类型的成员变量`imageCache`,用于存储已加载过的图片的软引用(`SoftReference&lt;Drawable&gt;`)。软引用允许Java垃圾回收机制在内存不足时自动清理这些对象,从而避免...

    java对象缓冲实现中间件

    3. **WeakReference/SoftReference**: 在内存管理中,弱引用和软引用可以用来解决缓存对象占用过多内存的问题。弱引用的对象在垃圾回收器运行时会被立即清除,而软引用的对象会在系统内存不足时才被回收。使用这些...

    Android内存泄漏[参考].pdf

    - 使用弱引用(WeakReference)、软引用(SoftReference)或虚引用(PhantomReference):这些引用不会阻止对象被垃圾收集,可以在需要时访问对象,但在内存紧张时允许GC回收。 - 注意线程局部变量:线程局部变量...

    hashCode内存溢出和内存泄漏的问题解决.docx

    除了以上提到的情况,还有其他可能导致内存泄漏的因素,例如线程局部变量(ThreadLocal)未被清理,或者过度使用软引用(SoftReference)、弱引用(WeakReference)等。为防止内存泄漏,开发者应关注以下几点: - ...

    Android实现异步加载图片

    1. **内存缓存**:为了加速图片加载,我们创建了一个内存缓存,使用HashMap存储图片的SoftReference对象。SoftReference是一种弱引用,当系统内存不足时,这些对象可能会被垃圾回收,从而释放内存。这样可以防止内存...

    leakcanary.zip

    在Android开发中,内存泄漏是一个常见但严重的问题,它可能导致应用性能下降,甚至崩溃。为了帮助开发者有效地检测和解决这个问题,一个名为LeakCanary的开源项目应运而生。LeakCanary是一款专门为Android设计的内存...

    ImageLoader的使用

    - **软引用(SoftReference)**:使用软引用来管理图像对象,这样当系统内存紧张时,这些对象可以被垃圾回收机制回收。 #### 2. 文件缓存 - **缓存目录**:利用`Context.getExternalCacheDir()`和`Context....

    实现了LRU算法的缓存

    - **get()**:当查找一个键时,如果在缓存中找到,将该键对应的节点移动到链表头部,并返回值。 - **put()**:向缓存中插入键值对时,首先检查是否已满。若满,则移除最不常使用的节点(链表尾部),然后将新节点...

    android异步加载图片.txt

    更优的方案是使用软引用(`SoftReference`)或者可回收的`Bitmap`选项(`BitmapOptions.inPurgeable`)来避免内存溢出。 2. **加载队列管理**:通过`PhotosQueue`类来管理图片的加载队列,确保每个`ImageView`只关联...

    java 内存泄露

    当一个类加载器被销毁时,其加载的所有类和实例应当随之被回收。但在某些情况下,如使用了WeakReference、SoftReference等弱引用,或者有线程局部变量(ThreadLocal)未正确清理,就可能导致类加载器无法被回收,...

    内存缓存技术

    - **弱引用与软引用**:利用Java提供的`WeakReference`和`SoftReference`机制,可以让垃圾回收器在内存紧张时自动回收不经常使用的缓存数据。 ##### 3.2 数据更新 除了内存占用之外,数据的有效性也是缓存技术中的...

    java performance13

    - 使用软引用(SoftReference)、弱引用(WeakReference)和虚引用(PhantomReference)可以帮助更好地管理对象的生命周期。 ### 进一步的性能优化策略 #### 系统资源利用的进一步考虑 1. **系统负载与资源分配**...

Global site tag (gtag.js) - Google Analytics