首先,引用对象在Java定义中有三种类型,从弱到强依次为:软引用、弱引用与虚引用,三种级别也各有所不一样(软引用>弱引用)。本文浅析下软引用与弱引用。大概的解释,软引用适合应用在须要cache的场景,通常面向实现内存敏感的缓存;弱引用则是适用在某些场景为了没法防止被回收的规范性映射,它优先级最低,通常与引用队列联合使用。javascript
详细介绍:
(一)强引用(默认存在)
强引用,是在实际开发中最为广泛的引用。有时候你开发的时候,申请一个内存空间的时候,就已是强引用了。例如:java
Object obj =new Object(); // 强引用
在强引用中,若是不让该对象指向为空,垃圾回收器绝对不会回收它。除非当出现内存空间不足的时候。jvm抛出oom致使程序异常种植的时候,才会回收具备强引用的对象来解决内存空间不足问题。android
Object obj =new Object(); // 强引用 obj = null;//这时候为垃圾回收器回收这个对象,至于何时回收,取决于垃圾回收器的算法
(二)软引用(SoftReference )
软引用对象也比较好理解,它是一个比较特殊的存在,拥有强引用的属性,又更加安全。若是有一个对象具备软引用。在内存空间足够的状况下,除非内存空间接近临界值、jvm即将抛出oom的时候,垃圾回收器才会将该引用对象进行回收,避免了系统内存溢出的状况。(前提也是对象指向不为空)所以,SoftReference 引用对象很是适合实现内存敏感的缓存,例如加载图片的时候,bitmap缓存机制。web
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
下面直接贴一份代码,同一份代码,比较在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环境中输出结果一致,这个笔者也匪夷所思...jvm
前,在平常开发中,其实对内存比较敏感的,例如Activity、webView、bitmap、Handler等等,举例若是咱们拥有一个管理Activity的管理类,即Activity须要暴露在外面,若是当前其中有一个Activity正在执行一个耗时的任务,若是使用强引用,这一系列过程很吃内存空间。
在咱们定义Handler的时候,细心的朋友就会发现,系统会抛出一个警告提示:“This Handler class should be static or leaks might occur(null)“,提示这样初始化引用可能会形成内存溢出。ide
那么咱们该怎么样避免?答案很简单,拒绝强引用,使用软引用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來源:简书简书著做权归做者全部,任何形式的转载都请联系做者得到受权并注明出处。