softreference的简单介绍

http://www.itjxue.com  2023-01-20 08:41  来源:未知  点击次数: 

理解StrongReference,SoftReference, WeakReference的区别

Java 中一共有 4 种类型的引用 : StrongReference、 SoftReference、 WeakReference 以及 PhantomReference (传说中的幽灵引用 呵呵),

这 4 种类型的引用与 GC 有着密切的关系,? 让我们逐一来看它们的定义和使用场景 :

1. Strong Reference

StrongReference 是 Java 的默认引用实现,? 它会尽可能长时间的存活于 JVM 内, 当没有任何对象指向它时 GC 执行后将会被回收

@Test?

public void strongReference() {?

Object referent =new Object();?

/**

? * 通过赋值创建 StrongReference

? ? */?

? ? Object strongReference = referent;?

? assertSame(referent, strongReference);?

referent =null;?

System.gc();?

/**

? ? * StrongReference 在 GC 后不会被回收,因为StrongReference 是用= ,强引用,如果再把strongReference=null 那将回收

? ? */?

assertNotNull(strongReference);?

}?

? 2. WeakReference WeakHashMap

WeakReference, 顾名思义,? 是一个弱引用,? 当所引用的对象在 JVM 内不再有强引用时, GC 后 weak reference 将会被自动回收

@Test?

public void weakReference() {?

Object referent =new Object();?

WeakReference weakRerference =new WeakReferenceObject(referent);?

assertSame(referent, weakRerference.get());?

referent =null;?

System.gc();?

/**

? ? * 一旦没有指向 referent 的强引用, weak reference 在 GC 后会被自动回收

? ? */?

assertNull(weakRerference.get());?

}?

WeakHashMap 使用 WeakReference 作为 key, 一旦没有指向 key 的强引用, WeakHashMap 在 GC 后将自动删除相关的 entry

@Test?

public void weakHashMap() throws InterruptedException {?

Map weakHashMap =new WeakHashMapObject, Object();?

Object key =new Object();?

Object value =new Object();?

? ? weakHashMap.put(key, value);?

? ? assertTrue(weakHashMap.containsValue(value));?

key =null;?

? System.gc();?

/**

? ? * 等待无效 entries 进入 ReferenceQueue 以便下一次调用 getTable 时被清理

? ? */?

Thread.sleep(1000);?

/**

? ? * 一旦没有指向 key 的强引用, WeakHashMap 在 GC 后将自动删除相关的 entry

? ? */?

? assertFalse(weakHashMap.containsValue(value));?

}?

3. SoftReference

SoftReference 于 WeakReference 的特性基本一致, 最大的区别在于 SoftReference 会尽可能长的保留引用直到 JVM 内存不足时才会被回收(虚拟机保证), 这一特性使得 SoftReference 非常适合缓存应用

@Test?

public void softReference() {?

Object referent =new Object();?

SoftReference softRerference =new SoftReferenceObject(referent);?

? ? assertNotNull(softRerference.get());?

referent =null;?

? ? System.gc();?

/**

? ? *? soft references 只有在 jvm OutOfMemory 之前才会被回收, 所以它非常适合缓存应用

? ? */?

? ? assertNotNull(softRerference.get());?

}?

强引用/软引用/弱引用/虚引用解析和应用场景分析

我们平常普通写的 Object a=new object(); 创建对象就是一种强引用

当内存不足,JVM开始垃圾回收, 对于强引用的对象,就算是出现了OOM也不会对该对象进行回收

强引用是我们最常见的普通对象引用,只要还有强引用指向一个对象,就能表明对象还“活着”,垃圾收集器不会碰这种对象。在Java中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的, 即使该对象以后永远都不会被用到JVM也不会回收。 因此强引用是造成Java内存泄漏的主要原因之一。

对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显式地将相应(强)引用赋值为null,一般认为就是可以被垃圾收集的了(当然具体回收时机还是要看垃圾收集策略)。

SoftReferenceObject softReference=new SoftReference(o1);

软引用是一种相对强引用弱化了一些的引用,需要用java.lang.ref.SoftReference类来实现,可以让对象豁免一些垃圾收集。

对于只有软引用的对象来说,

当系统内存充足时它不会被回收

当系统内存不足时它会被回收。

软引用通常用在对内存敏感的程序中,比如高速缓存就有用到软引用, 内存够用的时候就保留,不够用就回收!

弱引用需要用java.lang.ref.WeakReference类来实现,它比软引用的生存期更短

对于 只有弱引用的对象 来说,只要垃圾回收机制一运行, 不管JVM的内存空间是否足够,都会回收该对象占用的内存。

软引用/弱引用应用场景

场景模拟:

假如有一个应用需要读取大量的本地图片:

如果每次读取图片都从硬盘读取则会严重影响性能,如果一次性全部加载到内存中又可能造成内存溢出。

此时使用软引用可以解决这个问题。

弱引用之WeakHashMap

它是一个特殊的HashMap,属于import java.util.WeakHashMap;与HashMap平级;

它的特殊之处在于当它的某个键值对中的键失效或者为NULL的时候.弱此时发生了GC,那么该键值对将从WeakHashMap中移除;

注意若上述的key=Integer.valueOf(5),若这里key=null,不会让map移除这个键值对,因为这里key指向的是一个值而不是一个引用,当map.put时候直接把值放进去了,所以key=null时候不会影响 WeakHashMap

下面要将虚引用,在此之前,我们需要先了解一个东西,ReferenceQueue

软引用,弱引用,虚引用在创建时候可以直接传一个对象其实他们还有另外有一个构造方法是传一个对象和一个引用队列,这样会使他们回收之前保存到Reference里.

虚引用

虚引用需要java.lang.ref.PhantomReference类来实现。顾名思义,就是 形同虚设 ,与其他几种引用都不同,虚引用并不会决定对象的生命周期。

如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收 ,它不能单独使用也不能通过它访问对象, 虚引用必须和引用队列(ReferenceQueue)联合使用。

虚引用的主要作用是 跟踪对象被垃圾回收的状态 。仅仅是提供了一种确保对象被finalize以后,做某些事情的机制。PhantomReference的get方法总是返回null,因此无法访问对应的引用对象。 其意义在于说明一个对象已经进入finalization阶段,可以被gc回收,用来实现比finalization机制更灵活的回收操作。

换句话说, 设置虚引用关联的唯一目的,就是在这个对象被收集器回收的时候收到一个系统通知或者后续添加进一步的处理。

Java 技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。

四大引用和GCroot的杂糅

java WeakReference和SoftReference的区别

很早Java API就添加了弱引用(WeakReference)和软引用(SoftReference),引用类在垃圾回收工作的过程中有重要作用。我们都知道垃圾回收器会回收符合回收条件的对象的内存,但并不是所有的程序员都知道回收条件取决于指向该对象的 引用类型。

弱引用(weakReference)和softReference有什么区别?

弱引用对象,它们并不禁止其指示对象变得可终结,并被终结,然后被回收。弱引用最常用于实现规范化的映射。 假定垃圾回收器确定在某一时间点上某个对象是弱可到达对象。这时,它将自动清除针对此对象的所有弱引用,以及通过强引用链和软引用,可以从其到达该对象的针对任何其他弱可到达对象的所有弱引用。同时它将声明所有以前的弱可到达对象为可终结的。在同一时间或晚些时候,它将那些已经向引用队列注册的新清除的弱引用加入队列。 *******************************************************************************************

SoftReference:

软引用对象,在响应内存需要时,由垃圾回收器决定是否清除此对象。软引用对象最常用于实现内存敏感的缓存。 假定垃圾回收器确定在某一时间点某个对象是软可到达对象。这时,它可以选择自动清除针对该对象的所有软引用,以及通过强引用链,从其可以到达该对象的针对任何其他软可到达对象的所有软引用。在同一时间或晚些时候,它会将那些已经向引用队列注册的新清除的软引用加入队列。 软可到达对象的所有软引用都要保证在虚拟机抛出 OutOfMemoryError 之前已经被清除。否则,清除软引用的时间或者清除不同对象的一组此类引用的顺序将不受任何约束。然而,虚拟机实现不鼓励清除最近访问或使用过的软引用。 此类的直接实例可用于实现简单缓存;该类或其派生的子类还可用于更大型的数据结构,以实现更复杂的缓存。只要软引用的指示对象是强可到达对象,即正在实际使用的对象,就不会清除软引用。例如,通过保持最近使用的项的强指示对象,并由垃圾回收器决定是否放弃剩余的项,复杂的缓存可以防止放弃最近使用的项

****************************************************

weakReference一般用来防止内存泄漏,要保证内存被VM回收

四大引用

在一般的Java程序中,见到最多的就是强引用(strong reference)。如Date date = new Date(),date就是一个对象的强引用。对象的强引用可以在程序中到处传递。很多情况下,会同时有多个引用指向同一个对象。强引用的存在限制了对象在内存中的存活时间。假如对象A中包含了一个对象B的强引用,那么一般情况下,对象B的存活时间就不会短于对象A。如果对象A没有显式的把对象B的引用设为null的话,就只有当对象A被垃圾回收之后,对象B才不再有引用指向它,才可能获得被垃圾回收的机会。比如:Object object = new Object();。这里的object就是强引用,如果是在方法中创建,那么只要局部变量表还存在,就不会被回收。

软引用(soft reference)在强度上弱于强引用,通过类SoftReference来表示。它的作用是告诉垃圾回收器,程序中的哪些对象是不那么重要,当内存不足的时候是可以被暂时回收的。当JVM中的内存不足的时候,垃圾回收器会释放那些只被软引用所指向的对象。如果全部释放完这些对象之后,内存还不足,才会抛出OutOfMemory错误。软引用非常适合于创建缓存。当系统内存不足的时候,缓存中的内容是可以被释放的。但是并不是软引用的对象置null时就立马释放,是在内存不足时才释放,GC的时候并不会立马回收释放,因为GC并不一定代表内存不足。当垃圾回收器发现快要发生OOM的时候,软引用的对象就会被回收。即内存不足的时候,会回收软引用。

弱引用(weak reference)在强度上弱于软引用,通过类WeakReference来表示。它的作用是引用一个对象,但是并不阻止该对象被回收。如果使用一个强引用的话,只要该引用存在,那么被引用的对象是不能被回收的。弱引用则没有这个问题。在垃圾回收器运行的时候,如果一个对象的所有引用都是弱引用的话,该对象会被回收。就是在GC的时候就会立马回收

Handler中使用弱引用来保存Activity对象,就是因为Activity对象如果在Handler执行过程中被销毁回收,那么如果不使用弱引用,这时Activity在Handler中就是属于强引用,则不会被回收,这样就会造成了内存泄漏,而使用弱引用的话,就不会阻止Handler中的Activity对象被回收。

用来记录GC回收的对象,可以用来统计哪些对象被GC回收了。随时会被回收,但是不知道什么时候会回收。

一般软引用做缓存,比如Glide中;弱引用防泄漏;虚引用测泄漏,在JVM内部做一个检查

(责任编辑:IT教学网)

更多

推荐软件水平考试文章