软引用SoftReference[通俗易懂]

软引用SoftReference[通俗易懂]1.对象的引用类….  最近也是通过项目中知道了一些东西,涉及到了对象的引用类,对象的引用类分为多种,强引用(其实就是正常的引用),使用SoftReference实现软引用,WeakReference(弱引用) PhantomRefrence(虚引用)…这三个引用类我只详细的介绍一下SoftReference实现软引用…其他的就一笔带过….强引用:

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

1.对象的引用类….

  最近也是通过项目中知道了一些东西,涉及到了对象的引用类,对象的引用类分为多种,强引用(其实就是正常的引用),使用SoftReference实现软引用,Weak Reference(弱引用) PhantomRefrence(虚引用)…这三个引用类我只详细的介绍一下SoftReference实现软引用…其他的就一笔带过….

强引用:

Object darker=new Object();
Object darker_1=darker;
darker=null;
darker_1=null;

  强引用其实相对而言就非常的简单,也就是我们一般实例化对象后,对对象的一个引用就属于强引用,并且只要这个引用存在,那么GC(垃圾回收器)也就绝对不会去回收当前被引用的对象…如果将这个对象的引用设置为null,那么就代表GC可以对这个对象进行回收了…

软引用:

  软引用是我要细说的一个部分,先说一下软引用的一个引用目的,软引用的使用是与内存挂钩的一个引用类,主要应用于内存敏感的高速缓存,其实在Android中是经常使用的到的,由于Android的虚拟机是基于寄存器的Dalvik,它的堆大小只有16M,我们都清楚无论是Android应用程序,还是Java引用程序,在实例化对象的时候都是在堆中完成的…因此在Android中这个堆的大小要求确实是很苛刻的,一旦我们读取的资源数据过大,或者是内存里的对象由于声明的周期太长,没有被及时的释放,那么就很有可能造成OOM的发生…我们都知道GC的回收机制在正常的情况下并不是时时刻刻都在工作的,它的工作时间是不定期的,因此如果在GC不工作的期间我们的内存已经爆表,那就必定导致程序终止…OOM在Android是经常见到的一种情况,对象的不及时释放,static关键字的使用,线程不可控,还有最常见的就是在读取Bitmap的时候导致这种情况的发生…

  那么OOM是一个非常严重的问题,但是如果内存得不到充分的使用,这个其实也是一个潜在的问题,SoftReference(软引用),其实给我的感觉就是为了解决这样的问题,每一个对象通过软引用进行实例化,那么这个对象的数据也就会被保存起来,当需要再次调用这个对象中的数据的时候,只需要通过对象的get()方法就可以获取到该对象所保存的数据信息,其实也会是我们所说的cache,当内存快要不足的时候,GC会迅速的把所有的软引用清除掉,释放内存空间…这样不仅结合了对象的cache,同时还解决了OOM的发生,一举两得…虽然说是一举两得的东西,保证了内存能够安全的被使用,那么相反就要牺牲效率,在每一个软引用对象被实例化的时候,其实还是需要耗费许多的时间的…因此到底如何运用,取决于我们遇到的问题.

  简单的来一段小代码…

复制代码
Object obj=new Object();
SoftRefenrence sc = new SoftReference(obj);//这里使用了软引用...

/*
 *在这个期间,有可能会出现内存不足的情况发生,那么GC就会直接把所有的软引用全部清除..并释放内存空间
 *如果内存空间足够的话,那么就GC就不会进行工作...
 *GC的工作取决于内存的大小,以及其内部的算法,,,,
 */
   
if(sr!=null){
        //如果软引用还存在,那么直接就可以获取这个对象的相关数据...这样就实现了cache...
        obj = sr.get();

    }else{
        //如果已经不存在,表示GC已经将其回收,我们需要重新实例化对象,获取数据信息...
          
        obj = new Object();
        sr = new SoftReference(obj);
}
复制代码

  很简单的一段代码,没什么实际的意义,只是为了方便理解…在Android中,其实有一些时候还是由于Bitmap的问题导致内存不足的发生,图片相对而言还是比较大的,像素高的图片在读取的情况下是非常耗费内存的,如果读取的图片过多的话,那就更加的显而易见了,图片过多,内存会被吃的非常的紧,因此我们需要在Bitmap中去使用软引用,这样就可以避免OOM的发生…还可以有效的去使用内存…

  还是简单的说一下其中的道理,比如说我们读取到了一张图片,这张图片被读取后就以cache的形式保存起来…当我们的应用程序如果还是需要这张图片的资源数据的话,那么直接通过软引用中的get()方法,就可以得到图片中的资源数据,..这样就没必要再次进行读取了,直接从cache中就可以读取得到,如果图片过多,保存的对象也会越来越多,那么当内存将要发生OOM的时候,GC会迅速把所有的软引用,也就是这些对象的引用和内控件迅速释放…防止OOM的发生…下面贴一段小小的代码…

复制代码
import java.lang.ref.SoftReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import android.graphics.Bitmap;

public class MemoryCache {

    //将HashMap封装成一个线程安全的集合,并且使用软引用的方式防止OOM(内存不足)...
    //由于在ListView中会加载大量的图片.那么为了有效的防止OOM导致程序终止的情况...
    private Map<String,SoftReference<Bitmap>>cache=Collections.synchronizedMap(new HashMap<String, SoftReference<Bitmap>>());
    
    public Bitmap get(String id){
        if(!cache.containsKey(id))        
            return null;    
        SoftReference<Bitmap>ref=cache.get(id);
        return ref.get();
        
    }
    
    public void put(String id,Bitmap bitmap){
        cache.put(id, new SoftReference<Bitmap>(bitmap));
    }
    
    public void clear(){
        cache.clear();
    }
}
复制代码

  这段代码也非常的简单…就是定义了一个集合,将Bitmap的软引用保存在集合当中,如果图片资源存在于集合内部,那么直接就进行取出操作即可…如果存储的容量过大..超出了内存的限制..那么直接调用clear函数将其清空…这段代码隶属于一个项目中的小模块….

 

  最后简单的说一下弱引用…

  弱引用:

  弱引用其实和软引用差不太多,不过是使用WeakReference去实例化一个对象,并且GC是不会根据内存的原因去指定时间去回收对象…弱引用可以在未被GC回收之前的任意时间段,都能获取到这个对象的相关信息…一旦GC将其回收,那么就获取不到这个对象的相关数据了…该回收的时候,GC会自动的将其进行回收,不会根据内存的大小而决定时候去释放这个对象所占用的内存…简单的举个例子…

复制代码
Object obj = Object A();

    WeakReference wr = new WeakReference(obj);

    obj = null;

    //在这个时间段....短时间内GC不会被启动...那么我们就可以再次获取到这个对象保存的数据信息...
    //在这个期间如果GC启动了回收,那么就无法获取到这个对象所包含的数据信息了...

  if (wr.get()==null) {

  System.out.println("obj 已经被清除了 ");

  } else {

  System.out.println("obj 尚未被清除,其信息是 "+obj.toString());

  }

}
复制代码

  总之软引用的使用是为了解决OOM的状况发生…避免OOM的发生不仅仅只使用SoftReference,还有一些其他的方式,比如说减少static关键字的使用,在app中尽量去使用Application中的Context对象…避免线程不可控的情况发生,都是避免OOM的发生的方式…使用SoftReference更多的是在app中加载Bitmap而发生OOM…最后给大家一个源码..这个源码在上一篇文章发过了…这个源码中不仅包含BitmapFactory.Options,还包括SoftReference…还有一些零碎的知识点…总之大家看了这个源码…就能明白其中的道理….

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196063.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 【值得收藏】一份非常完整的Mysql规范

    做一个积极的人编码、改bug、提升自己我有一个乐园,面向编程,春暖花开!本文转载在,在原有内容基础上结合阿里巴巴Java开发手册中Mysql数据库章节的介绍,加上自己的理解和说明,整理而成。涉及的内容较多,建议收藏后仔细阅读!一、数据库命名规范数据库的表名、字段名必须使用小写字母或数字(不要使用驼峰哦),并禁止出现数字开头,禁止两个下划线中间只出现数字。正例:aliyun _ …

    2022年2月28日
    33
  • 打开GTA 5竟要跑19.8亿次if语句!黑客嘲讽R星代码烂,修改后直接省70%加载时间

    打开GTA 5竟要跑19.8亿次if语句!黑客嘲讽R星代码烂,修改后直接省70%加载时间本文转载自量子位一支烟的功夫,GTA5联机版终于打开了。「7年了!GTA5联机版加载还是这么慢??」△PleasewaitforevertoplayReddit、Steam、HackerNews上,无数玩家吐槽抱怨……进游戏少则等5、6分钟,多则20分钟。终于,一个黑客大哥实在忍不了,用逆编译器逐条查看运行情况,终于找到原因。原来,R星(游戏开发商RockStar)写的代码太低效,加载时,一个if语句竟然循环了19.8亿次….幕后黑手:谁占用大量时间?加

    2022年6月12日
    30
  • 微信小程序:wx.getUserInfo 接口的变动与使用

    微信小程序:wx.getUserInfo 接口的变动与使用

    2022年4月3日
    138
  • Springboot集成RocketMQ

    Springboot集成RocketMQ什么是RocketMQ?官方说明:随着使用越来越多的队列和虚拟主题,ActiveMQIO模块遇到了瓶颈。我们尽力通过节流,断路器或降级来解决此问题,但效果不佳。因此,我们那时开始关注流行的消息传递解决方案Kafka。不幸的是,Kafka不能满足我们的要求,特别是在低延迟和高可靠性方面。看到这里可以很清楚的知道RcoketMQ是一款低延迟、高可靠、可伸缩、易于使用的消息中间件。具…

    2022年6月3日
    34
  • 隶属度函数模板_高斯隶属度函数

    隶属度函数模板_高斯隶属度函数模糊隶属度函数划分等级根据国家对信号交叉路口的评价标准,对交通状况分为4个等级,分别为Ⅰ级舒适畅通、Ⅱ级接近饱和、Ⅲ级常呈混乱、Ⅳ级阻塞。因此选用4个等级的模糊隶属度函数。分别为:某时段交通状况对Ⅰ级路况的隶属度函数:        某时段交通状况对Ⅱ级路况的隶属度函数:        某时段交通状况对Ⅲ级路况的隶属度函数:        某时段交通状况对Ⅳ级

    2022年10月25日
    0
  • POJ1469_COURSES(二部图最大匹配)

    POJ1469_COURSES(二部图最大匹配)

    2022年1月15日
    39

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号