Java中内存优化的SoftReference 和 WeakReference浅析

一、引用对象类型定义

    首先,引用对象在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)则是适用在某些场景为了无法防止被回收的规范性映射,它优先级最低,一般与引用队列联合使用。而且,谷歌不推荐使用软引用。

傻小孩b mark
共勉,写给在成长路上奋斗的你

喜欢就为我点下喜欢吧:-D,感谢各位读者阅读。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容