• Java 对象引用方式 —— 强引用、软引用、弱引用和虚引用


    Java中负责内存回收的是JVM。通过JVM回收内存,我们不需要像使用C语音开发那样操心内存的使用,但是正因为不用操心内存的时候,也会导致在内存回收方面存在不够灵活的问题。

    为了解决内存操作不灵活的问题,我们可以通过了解Java的引用方式来解决这个问题。

    从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期。这四种级别由高到低依次为:强引用、软引用、弱引用和虚引用。

    下面我们来看一下四种级别的引用方式的特点:

    1.强引用

    我们使用的大部分的引用都是强引用,这是使用最普遍的引用。如果一个对象具有强引用,GC绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。

    2.软引用(SoftReference)

    如果一个对象只具有软引用,在内存空间足够的时候,GC不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要GC没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。

    软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被GC了,JAVA虚拟机就会把这个软引用加入到与之关联的引用队列中。

    3.弱引用(WeakReference)

    弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在GC扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程, 因此不一定会很快发现那些只具有弱引用的对象。 

    弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

    4.虚引用(PhantomReference)

    "虚引用"顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。

    如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。

     

    Android 开发中会使用到弱引用或者软引用的地方

    1.解决Handler可能造成的内存泄露 -- 使用弱引用

    当使用内部类(包括匿名类)来创建Handler的时候,Handler对象会隐式地持有一个外部类对象(通常是一个Activity)的引用,不然你怎么可能通过Handler来操作Activity中的View。而Handler通常会伴随着一个耗时的后台线程(例如从网络拉取图片)一起出现,这个后台线程在任务执行完毕(例如图片下载完毕)之后,通过消息机制通知Handler,然后Handler把图片更新到界面。

    然而,如果用户在网络请求过程中关闭了Activity,正常情况下,Activity不再被使用,它就有可能在GC检查时被回收掉,但由于这时线程尚未执行完,而该线程持有Handler的引用(不然它怎么发消息给Handler?),这个Handler又持有Activity的引用,就导致该Activity无法被回收(即内存泄露),直到网络请求结束(例如图片下载完毕)。

    2.解决图片加载时,可能造成的内存不足问题 -- 使用软引用

    使用软引用相对使用强引用,在图片加载方面能够很明显的提升性能,并减少崩溃的几率,与Lru算法指定LruCache能够更好的去管理,因为增加了根据图片使用频率来管理内存的算法,相比较更加合理和人性化。

     

  • 相关阅读:
    jsp中上传图片(使用ajaxfileupload)
    快慢的悖论
    为什么所有的架构都是糟糕的
    软件项目是这样失败的。
    初识微信小程序
    Hibernate hql getHibernateTemplate()常用方法汇总
    JAVA中关于set()和get()方法的理解及使用
    java性能调优实战
    PLSQL显示乱码-无法进行中文条件查询解决
    Oracle 10g bigfile表空间简介
  • 原文地址:https://www.cnblogs.com/renhui/p/6069437.html
Copyright © 2020-2023  润新知