Java语言中内存优化的SoftReference 和 WeakReference的对比分析
小标 2018-12-04 来源 : 阅读 1276 评论 0

摘要:本文主要向大家介绍了Java语言中内存优化的SoftReference 和 WeakReference的对比分析,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

本文主要向大家介绍了Java语言中内存优化的SoftReference 和 WeakReference的对比分析,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

一、引用对象类型定义


首先,引用对象在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环境运行情况:



Android运行环境



从上面的情况,我们还让你容易可以观察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)“,提示这样初始化引用可能会造成内存溢出。<喎�"/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPjxpbWcgYWx0PQ=="这里写图片描述" src="/uploadfile/Collfiles/20180518/20180518091938133.png" title="\" />


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


static class MyHandler extends Handler{

 

        WeakReferencemActivity;

 

        MyHandler(Activityactivity){

            mActivity=newWeakReference(activity);

        }

 

        @Override

        publicvoidhandleMessage(Messagemsg){

            Activity activity=mActivity.get();

            switch(msg.what){

                case 1000:

                    //doing...

                    break;

            }

        }

    }

</activity></activity>

   


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


四、总结


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


          

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注编程语言JAVA频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved