美文网首页
Java弱引用之硬核复用机制

Java弱引用之硬核复用机制

作者: 风逝_c609 | 来源:发表于2020-04-13 15:21 被阅读0次

弱引用不是回收了吗?怎么还复用???下面咱们来一探究竟

1. 弱引用的常规使用

class Resource {
    Object data;

    public Resource(Object data) {
        this.data = data;
    }

    public Object getData() {
        return data;
    }
}

写代码用弱引用测试一把

    @Test
    public void testWeakFirst() {
        Resource resource = new Resource("data can re-use");
        WeakReference<Resource> weakReference = new WeakReference(resource);

        System.out.println("before gc");
        System.out.println("resource = " + resource);
        System.out.println("weakRef = " + weakReference.get());

        System.out.println("after gc");
        resource = null;
        System.gc();
        System.out.println("resource = " + resource);
        System.out.println("weakRef = " + weakReference.get());
    }

Run一把毫无悬念的结果

before gc
resource = team.opay.pay.Resource@484b61fc
weakRef = team.opay.pay.Resource@484b61fc
after gc
resource = null
weakRef = java.lang.ref.WeakReference@45fe3ee3
weakRef.get = null

Process finished with exit code 0

常规弱引用使用测试结论

  • 弱引用包裹的对象resource返回null
  • 但是弱引用本身是(WeakReference != null)

2. 扩展WeakReference

2.1 简单扩展(不使用引用队列)
class ReuseWeakReferenceI extends WeakReference<Resource> {

    private String key;
    private Object source;

    public ReuseWeakReferenceI(String key, Resource referent) {
        super(referent);
        /**
         * 这里为什么是Resource的data字段呢?
         * 因为get方法毫无悬念的为空 可以尝试引用一下起内部的变量
         */
        this.source = referent.getData();
        this.key = key;
    }

    public Object getSource() {
        return source;
    }

    public String getKey() {
        return key;
    }

    public void reset() {
        this.key = null;
        this.source = null;// 让gc尽快回收
        clear();
    }
}

测试代码如下

    @Test
    public void testWeakSecond() {
        Resource resource = new Resource("data can re-use");
        ReuseWeakReferenceI weakReference = new ReuseWeakReferenceI("", resource);

        System.out.println("before gc");
        System.out.println("resource = " + resource);
        System.out.println("weakRef = " + weakReference.get());

        System.out.println("after gc");
        resource = null;
        System.gc();
        System.out.println("resource = " + resource);
        System.out.println("weakRef = " + weakReference);
        System.out.println("weakRef.get = " + weakReference.get());
        System.out.println("weakRef.get = " + weakReference.getSource());
    }

继续Run

before gc
resource = team.opay.pay.Resource@484b61fc
weakRef = team.opay.pay.Resource@484b61fc
after gc
resource = null
weakRef = team.opay.pay.ReuseWeakReferenceI@45fe3ee3
weakRef.get = null
weakRef.data = data can re-use

2.1无引用队列测试结论
-WeakReference引用在,其内部强引用也就在

2.2 扩展(使用引用队列)
class ReuseWeakReference extends WeakReference<Resource> {

    private String key;
    private Object source;

    public ReuseWeakReference(String key, Resource referent, ReferenceQueue<? super Resource> q) {
        super(referent, q);
        /**
         * 这里为什么是Resource的data字段呢?
         * 因为get方法毫无悬念的为空 可以尝试引用一下起内部的变量
         */
        this.source = referent.getData();
        this.key = key;
    }

    public Object getSource() {
        return source;
    }

    public String getKey() {
        return key;
    }

    public void reset() {
        this.key = null;
        this.source = null;// 让gc尽快回收
        clear();
    }
}

测试代码

@Test
    public void testLast() {
        String key = "sourceKey";
        Resource resource = new Resource("data can re-use");
        ReferenceQueue<Resource> referenceQueue = new ReferenceQueue<>();
        ReuseWeakReference weakReference = new ReuseWeakReference(key, resource, referenceQueue);
        Map<String, ReuseWeakReference> cache = new HashMap<>();
        cache.put(key, weakReference);

        System.out.println("before call gc");
        System.out.println("resource = " + resource);
        System.out.println("weakRef = " + weakReference.get());

        resource = null;
        System.gc();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("after call gc");
        System.out.println("resource = " + resource);
        System.out.println("weakRef = " + weakReference.get());
        Reference reference;
        while ((reference = referenceQueue.poll()) != null) {
            ReuseWeakReference reuse = (ReuseWeakReference)reference;
            System.out.println("weakCacheMap size(before remove) = " + cache.size());
            cache.remove(reuse.getKey());
            System.out.println("weakCacheMap size(after remove) = " + cache.size());
            System.out.println("weakRef.queue reuse value = " + reuse.getSource());
        }
    }

运行结果

before call gc
resource = team.opay.pay.Resource@484b61fc
weakRef = team.opay.pay.Resource@484b61fc
after call gc
resource = null
weakRef = null
weakCacheMap size(before remove) = 1
weakCacheMap size(after remove) = 0
weakRef.queue ref.data (in memory) = data can re-use

2.2使用引用队列扩展测试结论

  • (同2.1测试结论)

3. Andorid Glide实践

Glide ActiveResources之弱引用复用实践篇
当检测到正在使用的缓存不在使用时,有如下复用处理

  • bitmap.recycle()
  • cache.put() //memoryCache
  • bitmapPool //inMutable

相关文章

  • Java弱引用之硬核复用机制

    弱引用不是回收了吗?怎么还复用???下面咱们来一探究竟 1. 弱引用的常规使用 写代码用弱引用测试一把 Run一把...

  • ListView总结

    复用机制 listview 的item会创建至少是一屏幕可显示的数量,新的item会复用之前的旧item,大大提高...

  • Java线程池复用机制

    线程复用的实质就是在Tread内的Runnable的run()方法中不断的获取任务,执行任务。 线程池内将保留核心...

  • Java同步机制之volatile

    Java并发系列番外篇——同步机制(二) Java提供了一种稍弱的同步机制,即volatile变量,用来确保将更新...

  • IO多路复用之poll总结

    参考链接:IO多路复用之poll总结 搞不懂,为什么Xcode下无法调试了; 1、基本知识 poll的机制与sel...

  • RecyclerView的复用(缓存)和回收机制

    本篇文章从源码的角度分析RecyclerView的复用和回收的原理机制 复用机制 RecyclerView的复用机...

  • 复用之艰

    最近几年,中台之风盛行,各行各业都希望能建设自己的”大中台,小前台“,期望能够通过强大中台的复用能力快速的赋能业务...

  • java面试知识点

    java相关 1.Java内存模型(JSR133 happen-before 内存重排序) 2.垃圾回收算法,弱引...

  • java中的引用

    Java 中除了强引用之外,还提供了其它低级别的引用 对象可达状态: 在强引用之外,弱引用可以泛化成多种不同强度的...

  • 蓄谋已久的列表控件

    之前分析了 事件分布 和 ListView复用机制 ,不能只分析不使用把,这次就用之前分析的知识来完成一个自定义列...

网友评论

      本文标题:Java弱引用之硬核复用机制

      本文链接:https://www.haomeiwen.com/subject/glygmhtx.html