zoukankan      html  css  js  c++  java
  • java软引用、弱引用(转摘)

    本文转自网络,源地址:https://www.jianshu.com/p/b56731447179

    一、引用对象类型定义

        首先,引用对象在Java定义中有三种类型,从弱到强依次为:软引用、弱引用与虚引用,三种级别也各有所不同(软引用>弱引用)。本文浅析下软引用与弱引用。大概的解释,软引用适合应用在需要cache的场景,一般面向实现内存敏感的缓存;弱引用则是适用在某些场景为了无法防止被回收的规范性映射,它优先级最低,一般与引用队列联合使用。

    详细介绍:
    (一)强引用(默认存在)
        强引用,是在实际开发中最为普遍的引用。有时候你开发的时候,申请一个内存空间的时候,就已经是强引用了。例如:

         Object obj =new Object();  // 强引用
    

        在强引用中,如果不让该对象指向为空,垃圾回收器绝对不会回收它。除非当出现内存空间不足的时候。jvm抛出oom导致程序异常种植的时候,才会回收具有强引用的对象来解决内存空间不足问题。

       Object obj =new Object();  // 强引用
       obj = null;//这时候为垃圾回收器回收这个对象,至于什么时候回收,取决于垃圾回收器的算法
    

    (二)软引用(SoftReference )
        软引用对象也比较好理解,它是一个比较特殊的存在,拥有强引用的属性,又更加安全。如果有一个对象具有软引用。在内存空间足够的情况下,除非内存空间接近临界值、jvm即将抛出oom的时候,垃圾回收器才会将该引用对象进行回收,避免了系统内存溢出的情况。(前提也是对象指向不为空)因此,SoftReference 引用对象非常适合实现内存敏感的缓存,例如加载图片的时候,bitmap缓存机制。

    String value = new String(“sy”);
    SoftReference sfRefer = new SoftReference (value );
    
    sfRefer .get();//可以获得引用对象值
    

    (三)弱引用(WeakReference)
        顾名思义,一个具有弱引用的对象,与软引用对比来说,前者的生命周期更短。当垃圾回收器扫描到弱引用的对象的时候,不管内存空间是否足够,都会直接被垃圾回收器回收。不过也不用特别担心,垃圾回收器是一个优先级比较低的现场,因此不一定很快可以发现弱引用的对象。
       另外,google官方是推荐Android开发者使用WeakReference,而不建议SoftReference 引用,Android环境下与纯Java有所略同。下面待会说明情况。

    String value = new String(“sy”);
    WeakReference weakRefer = new WeakReference(value );
    
    System.gc();
    
    weakRefer.get();//null
    

    二、Java环境与Android环境对比异同点

    下面直接贴一份代码,同一份代码,比较在android环境下输出的结果与Java输出的结果:

        public static void main(String[] args) throws InterruptedException {
    
            initsoftReference();
            initweakReference();
            
            Thread.sleep(2000);
            System.gc();
            
            if (softReference.get() == null) {
                System.out.println("SoftReference : " + "null");
            }else{
                System.out.println("SoftReference : " + softReference.get());
            }
    
    
            if (weakReference.get() == null) {
                System.out.println("WeakReference : " + "null");
            }else{
                System.out.println("WeakReference : " + weakReference.get());
            }
            
        }
    
        private static void initsoftReference() {
            softReference = new SoftReference(value_soft);
            value_soft = null;
        }
    
        private static void initweakReference() {
            weakReference = new WeakReference(value_weak);
            value_weak = null;
        }
    
    

    纯Java环境运行情况:

     
    java运行.png

    Android环境运行情况:

     
    Android运行.png

        从上面的情况,我们还让你容易可以观察Android环境下与纯Java环境下两者直接的输出结果不同!在Android环境下WeakReference 与SoftReference 两者输出结果一样。其实对于手机系统存在多应用,又对于内存是比较敏感的,自然对于内存释放会更加严格。试想一下,如果众多对象使用 SoftReference引用,大部分都是这也是为什么google不建议SoftReference 的原因之一,至于软引用与弱引用在android环境中输出结果一致,这个笔者也匪夷所思...

    三、实战应用内存优化策略避免Handler内存泄漏

        前,在日常开发中,其实对内存比较敏感的,例如Activity、webView、bitmap、Handler等等,举例如果我们拥有一个管理Activity的管理类,即Activity需要暴露在外面,如果当前其中有一个Activity正在执行一个耗时的任务,如果使用强引用,这一系列过程很吃内存空间。
        在我们定义Handler的时候,细心的朋友就会发现,系统会抛出一个警告提示:“This Handler class should be static or leaks might occur(null)“,提示这样初始化引用可能会造成内存溢出。

     
    QQ截图20160809092738.png

        那么我们该怎么样避免?答案很简单,拒绝强引用,使用软引用WeakReference,贴下代码:

        static class MyHandler extends Handler{
    
            WeakReference<Activity>mActivity;
    
            MyHandler(Activityactivity){
                mActivity=newWeakReference<Activity>(activity);
            }
    
            @Override
            publicvoidhandleMessage(Messagemsg){
                Activity activity=mActivity.get();
                switch(msg.what){
                    case 1000:
                        //doing...
                        break;
                }
            }
        }
    

        由于Handler加入作为内部类,这说明了它必须保留外部类的引用,例如Activity需要向外面暴露给Handler,Handler必须一直保持他外部类的引用,如果外部类引用为强引用,很容易出现内存泄漏的情况。

    四、总结

        总之,对比纯Java环境,对于面向移动终端的Android系统,对于缓存机制比较敏感,以及对于内存管理更加严格。软引用(SoftReference)适合应用在需要cache的场景,一般面向实现内存敏感的缓存;弱引用(WeakReference)则是适用在某些场景为了无法防止被回收的规范性映射,它优先级最低,一般与引用队列联合使用。而且,谷歌不推荐使用软引用。



    作者:DevSiven
    链接:https://www.jianshu.com/p/b56731447179
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

  • 相关阅读:
    学习Jammendo代码的心路历程(二)ViewFlipper数据的填充
    学习Jammendo代码的心路历程(一)简单的淡出效果实现
    面向对象的一小步:添加ActiveRecord的Scope功能
    关于token和refresh token
    一个极为简单的方法实现本地(离线)yum安装rpm包
    Yii2基本概念之——生命周期(LifeCycle)
    一篇文章说透Nginx的rewrite模块
    PHP Session 常用的函数
    Session 的原理及最佳实践
    Yii2基本概念之——配置(Configurations)
  • 原文地址:https://www.cnblogs.com/ixixi/p/9467026.html
Copyright © 2011-2022 走看看